* Makefile.def (target_modules): Add libssp.
[official-gcc.git] / gcc / config / i386 / i386.md
blobc0823b608d8a9c7b6d19b89bd94edf8c15a1578e
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, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, 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)
142    ; SSP patterns
143    (UNSPEC_SP_SET               100)
144    (UNSPEC_SP_TEST              101)
145    (UNSPEC_SP_TLS_SET           102)
146    (UNSPEC_SP_TLS_TEST          103)
147   ])
149 (define_constants
150   [(UNSPECV_BLOCKAGE            0)
151    (UNSPECV_STACK_PROBE         1)
152    (UNSPECV_EMMS                2)
153    (UNSPECV_LDMXCSR             3)
154    (UNSPECV_STMXCSR             4)
155    (UNSPECV_FEMMS               5)
156    (UNSPECV_CLFLUSH             6)
157    (UNSPECV_ALIGN               7)
158    (UNSPECV_MONITOR             8)
159    (UNSPECV_MWAIT               9)
160    (UNSPECV_CMPXCHG_1           10)
161    (UNSPECV_CMPXCHG_2           11)
162    (UNSPECV_XCHG                12)
163    (UNSPECV_LOCK                13)
164   ])
166 ;; Registers by name.
167 (define_constants
168   [(BP_REG                       6)
169    (SP_REG                       7)
170    (FLAGS_REG                   17)
171    (FPSR_REG                    18)
172    (DIRFLAG_REG                 19)
173   ])
175 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
176 ;; from i386.c.
178 ;; In C guard expressions, put expressions which may be compile-time
179 ;; constants first.  This allows for better optimization.  For
180 ;; example, write "TARGET_64BIT && reload_completed", not
181 ;; "reload_completed && TARGET_64BIT".
184 ;; Processor type.  This attribute must exactly match the processor_type
185 ;; enumeration in i386.h.
186 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
187   (const (symbol_ref "ix86_tune")))
189 ;; A basic instruction type.  Refinements due to arguments to be
190 ;; provided in other attributes.
191 (define_attr "type"
192   "other,multi,
193    alu,alu1,negnot,imov,imovx,lea,
194    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
195    icmp,test,ibr,setcc,icmov,
196    push,pop,call,callv,leave,
197    str,cld,
198    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
199    sselog,sselog1,sseiadd,sseishft,sseimul,
200    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
201    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
202   (const_string "other"))
204 ;; Main data type used by the insn
205 (define_attr "mode"
206   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
207   (const_string "unknown"))
209 ;; The CPU unit operations uses.
210 (define_attr "unit" "integer,i387,sse,mmx,unknown"
211   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
212            (const_string "i387")
213          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
214                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
215            (const_string "sse")
216          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
217            (const_string "mmx")
218          (eq_attr "type" "other")
219            (const_string "unknown")]
220          (const_string "integer")))
222 ;; The (bounding maximum) length of an instruction immediate.
223 (define_attr "length_immediate" ""
224   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
225            (const_int 0)
226          (eq_attr "unit" "i387,sse,mmx")
227            (const_int 0)
228          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
229                           imul,icmp,push,pop")
230            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
231          (eq_attr "type" "imov,test")
232            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
233          (eq_attr "type" "call")
234            (if_then_else (match_operand 0 "constant_call_address_operand" "")
235              (const_int 4)
236              (const_int 0))
237          (eq_attr "type" "callv")
238            (if_then_else (match_operand 1 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          ;; We don't know the size before shorten_branches.  Expect
242          ;; the instruction to fit for better scheduling.
243          (eq_attr "type" "ibr")
244            (const_int 1)
245          ]
246          (symbol_ref "/* Update immediate_length and other attributes! */
247                       gcc_unreachable (),1")))
249 ;; The (bounding maximum) length of an instruction address.
250 (define_attr "length_address" ""
251   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
252            (const_int 0)
253          (and (eq_attr "type" "call")
254               (match_operand 0 "constant_call_address_operand" ""))
255              (const_int 0)
256          (and (eq_attr "type" "callv")
257               (match_operand 1 "constant_call_address_operand" ""))
258              (const_int 0)
259          ]
260          (symbol_ref "ix86_attr_length_address_default (insn)")))
262 ;; Set when length prefix is used.
263 (define_attr "prefix_data16" ""
264   (if_then_else (ior (eq_attr "mode" "HI")
265                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
266     (const_int 1)
267     (const_int 0)))
269 ;; Set when string REP prefix is used.
270 (define_attr "prefix_rep" "" 
271   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
272     (const_int 1)
273     (const_int 0)))
275 ;; Set when 0f opcode prefix is used.
276 (define_attr "prefix_0f" ""
277   (if_then_else 
278     (ior (eq_attr "type" "imovx,setcc,icmov")
279          (eq_attr "unit" "sse,mmx"))
280     (const_int 1)
281     (const_int 0)))
283 ;; Set when REX opcode prefix is used.
284 (define_attr "prefix_rex" ""
285   (cond [(and (eq_attr "mode" "DI")
286               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
287            (const_int 1)
288          (and (eq_attr "mode" "QI")
289               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
290                   (const_int 0)))
291            (const_int 1)
292          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
293              (const_int 0))
294            (const_int 1)
295         ]
296         (const_int 0)))
298 ;; Set when modrm byte is used.
299 (define_attr "modrm" ""
300   (cond [(eq_attr "type" "str,cld,leave")
301            (const_int 0)
302          (eq_attr "unit" "i387")
303            (const_int 0)
304          (and (eq_attr "type" "incdec")
305               (ior (match_operand:SI 1 "register_operand" "")
306                    (match_operand:HI 1 "register_operand" "")))
307            (const_int 0)
308          (and (eq_attr "type" "push")
309               (not (match_operand 1 "memory_operand" "")))
310            (const_int 0)
311          (and (eq_attr "type" "pop")
312               (not (match_operand 0 "memory_operand" "")))
313            (const_int 0)
314          (and (eq_attr "type" "imov")
315               (and (match_operand 0 "register_operand" "")
316                    (match_operand 1 "immediate_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "call")
319               (match_operand 0 "constant_call_address_operand" ""))
320              (const_int 0)
321          (and (eq_attr "type" "callv")
322               (match_operand 1 "constant_call_address_operand" ""))
323              (const_int 0)
324          ]
325          (const_int 1)))
327 ;; The (bounding maximum) length of an instruction in bytes.
328 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
329 ;; Later we may want to split them and compute proper length as for
330 ;; other insns.
331 (define_attr "length" ""
332   (cond [(eq_attr "type" "other,multi,fistp,frndint")
333            (const_int 16)
334          (eq_attr "type" "fcmp")
335            (const_int 4)
336          (eq_attr "unit" "i387")
337            (plus (const_int 2)
338                  (plus (attr "prefix_data16")
339                        (attr "length_address")))]
340          (plus (plus (attr "modrm")
341                      (plus (attr "prefix_0f")
342                            (plus (attr "prefix_rex")
343                                  (const_int 1))))
344                (plus (attr "prefix_rep")
345                      (plus (attr "prefix_data16")
346                            (plus (attr "length_immediate")
347                                  (attr "length_address")))))))
349 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
350 ;; `store' if there is a simple memory reference therein, or `unknown'
351 ;; if the instruction is complex.
353 (define_attr "memory" "none,load,store,both,unknown"
354   (cond [(eq_attr "type" "other,multi,str")
355            (const_string "unknown")
356          (eq_attr "type" "lea,fcmov,fpspc,cld")
357            (const_string "none")
358          (eq_attr "type" "fistp,leave")
359            (const_string "both")
360          (eq_attr "type" "frndint")
361            (const_string "load")
362          (eq_attr "type" "push")
363            (if_then_else (match_operand 1 "memory_operand" "")
364              (const_string "both")
365              (const_string "store"))
366          (eq_attr "type" "pop")
367            (if_then_else (match_operand 0 "memory_operand" "")
368              (const_string "both")
369              (const_string "load"))
370          (eq_attr "type" "setcc")
371            (if_then_else (match_operand 0 "memory_operand" "")
372              (const_string "store")
373              (const_string "none"))
374          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
375            (if_then_else (ior (match_operand 0 "memory_operand" "")
376                               (match_operand 1 "memory_operand" ""))
377              (const_string "load")
378              (const_string "none"))
379          (eq_attr "type" "ibr")
380            (if_then_else (match_operand 0 "memory_operand" "")
381              (const_string "load")
382              (const_string "none"))
383          (eq_attr "type" "call")
384            (if_then_else (match_operand 0 "constant_call_address_operand" "")
385              (const_string "none")
386              (const_string "load"))
387          (eq_attr "type" "callv")
388            (if_then_else (match_operand 1 "constant_call_address_operand" "")
389              (const_string "none")
390              (const_string "load"))
391          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
392               (match_operand 1 "memory_operand" ""))
393            (const_string "both")
394          (and (match_operand 0 "memory_operand" "")
395               (match_operand 1 "memory_operand" ""))
396            (const_string "both")
397          (match_operand 0 "memory_operand" "")
398            (const_string "store")
399          (match_operand 1 "memory_operand" "")
400            (const_string "load")
401          (and (eq_attr "type"
402                  "!alu1,negnot,ishift1,
403                    imov,imovx,icmp,test,
404                    fmov,fcmp,fsgn,
405                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
406                    mmx,mmxmov,mmxcmp,mmxcvt")
407               (match_operand 2 "memory_operand" ""))
408            (const_string "load")
409          (and (eq_attr "type" "icmov")
410               (match_operand 3 "memory_operand" ""))
411            (const_string "load")
412         ]
413         (const_string "none")))
415 ;; Indicates if an instruction has both an immediate and a displacement.
417 (define_attr "imm_disp" "false,true,unknown"
418   (cond [(eq_attr "type" "other,multi")
419            (const_string "unknown")
420          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
421               (and (match_operand 0 "memory_displacement_operand" "")
422                    (match_operand 1 "immediate_operand" "")))
423            (const_string "true")
424          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
425               (and (match_operand 0 "memory_displacement_operand" "")
426                    (match_operand 2 "immediate_operand" "")))
427            (const_string "true")
428         ]
429         (const_string "false")))
431 ;; Indicates if an FP operation has an integer source.
433 (define_attr "fp_int_src" "false,true"
434   (const_string "false"))
436 ;; Defines rounding mode of an FP operation.
438 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
439   (const_string "any"))
441 ;; Describe a user's asm statement.
442 (define_asm_attributes
443   [(set_attr "length" "128")
444    (set_attr "type" "multi")])
446 ;; All x87 floating point modes
447 (define_mode_macro X87MODEF [SF DF XF])
449 ;; All integer modes handled by x87 fisttp operator.
450 (define_mode_macro X87MODEI [HI SI DI])
452 ;; All integer modes handled by integer x87 operators.
453 (define_mode_macro X87MODEI12 [HI SI])
455 ;; All SSE floating point modes
456 (define_mode_macro SSEMODEF [SF DF])
458 ;; All integer modes handled by SSE cvtts?2si* operators.
459 (define_mode_macro SSEMODEI24 [SI DI])
462 ;; Scheduling descriptions
464 (include "pentium.md")
465 (include "ppro.md")
466 (include "k6.md")
467 (include "athlon.md")
470 ;; Operand and operator predicates
472 (include "predicates.md")
475 ;; Compare instructions.
477 ;; All compare insns have expanders that save the operands away without
478 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
479 ;; after the cmp) will actually emit the cmpM.
481 (define_expand "cmpdi"
482   [(set (reg:CC FLAGS_REG)
483         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
484                     (match_operand:DI 1 "x86_64_general_operand" "")))]
485   ""
487   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
488     operands[0] = force_reg (DImode, operands[0]);
489   ix86_compare_op0 = operands[0];
490   ix86_compare_op1 = operands[1];
491   DONE;
494 (define_expand "cmpsi"
495   [(set (reg:CC FLAGS_REG)
496         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
497                     (match_operand:SI 1 "general_operand" "")))]
498   ""
500   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
501     operands[0] = force_reg (SImode, operands[0]);
502   ix86_compare_op0 = operands[0];
503   ix86_compare_op1 = operands[1];
504   DONE;
507 (define_expand "cmphi"
508   [(set (reg:CC FLAGS_REG)
509         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
510                     (match_operand:HI 1 "general_operand" "")))]
511   ""
513   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
514     operands[0] = force_reg (HImode, operands[0]);
515   ix86_compare_op0 = operands[0];
516   ix86_compare_op1 = operands[1];
517   DONE;
520 (define_expand "cmpqi"
521   [(set (reg:CC FLAGS_REG)
522         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
523                     (match_operand:QI 1 "general_operand" "")))]
524   "TARGET_QIMODE_MATH"
526   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
527     operands[0] = force_reg (QImode, operands[0]);
528   ix86_compare_op0 = operands[0];
529   ix86_compare_op1 = operands[1];
530   DONE;
533 (define_insn "cmpdi_ccno_1_rex64"
534   [(set (reg FLAGS_REG)
535         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
536                  (match_operand:DI 1 "const0_operand" "n,n")))]
537   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
538   "@
539    test{q}\t{%0, %0|%0, %0}
540    cmp{q}\t{%1, %0|%0, %1}"
541   [(set_attr "type" "test,icmp")
542    (set_attr "length_immediate" "0,1")
543    (set_attr "mode" "DI")])
545 (define_insn "*cmpdi_minus_1_rex64"
546   [(set (reg FLAGS_REG)
547         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
548                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
549                  (const_int 0)))]
550   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
551   "cmp{q}\t{%1, %0|%0, %1}"
552   [(set_attr "type" "icmp")
553    (set_attr "mode" "DI")])
555 (define_expand "cmpdi_1_rex64"
556   [(set (reg:CC FLAGS_REG)
557         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
558                     (match_operand:DI 1 "general_operand" "")))]
559   "TARGET_64BIT"
560   "")
562 (define_insn "cmpdi_1_insn_rex64"
563   [(set (reg FLAGS_REG)
564         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
565                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
566   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
567   "cmp{q}\t{%1, %0|%0, %1}"
568   [(set_attr "type" "icmp")
569    (set_attr "mode" "DI")])
572 (define_insn "*cmpsi_ccno_1"
573   [(set (reg FLAGS_REG)
574         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
575                  (match_operand:SI 1 "const0_operand" "n,n")))]
576   "ix86_match_ccmode (insn, CCNOmode)"
577   "@
578    test{l}\t{%0, %0|%0, %0}
579    cmp{l}\t{%1, %0|%0, %1}"
580   [(set_attr "type" "test,icmp")
581    (set_attr "length_immediate" "0,1")
582    (set_attr "mode" "SI")])
584 (define_insn "*cmpsi_minus_1"
585   [(set (reg FLAGS_REG)
586         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
587                            (match_operand:SI 1 "general_operand" "ri,mr"))
588                  (const_int 0)))]
589   "ix86_match_ccmode (insn, CCGOCmode)"
590   "cmp{l}\t{%1, %0|%0, %1}"
591   [(set_attr "type" "icmp")
592    (set_attr "mode" "SI")])
594 (define_expand "cmpsi_1"
595   [(set (reg:CC FLAGS_REG)
596         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
597                     (match_operand:SI 1 "general_operand" "ri,mr")))]
598   ""
599   "")
601 (define_insn "*cmpsi_1_insn"
602   [(set (reg FLAGS_REG)
603         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
604                  (match_operand:SI 1 "general_operand" "ri,mr")))]
605   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
606     && ix86_match_ccmode (insn, CCmode)"
607   "cmp{l}\t{%1, %0|%0, %1}"
608   [(set_attr "type" "icmp")
609    (set_attr "mode" "SI")])
611 (define_insn "*cmphi_ccno_1"
612   [(set (reg FLAGS_REG)
613         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
614                  (match_operand:HI 1 "const0_operand" "n,n")))]
615   "ix86_match_ccmode (insn, CCNOmode)"
616   "@
617    test{w}\t{%0, %0|%0, %0}
618    cmp{w}\t{%1, %0|%0, %1}"
619   [(set_attr "type" "test,icmp")
620    (set_attr "length_immediate" "0,1")
621    (set_attr "mode" "HI")])
623 (define_insn "*cmphi_minus_1"
624   [(set (reg FLAGS_REG)
625         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
626                            (match_operand:HI 1 "general_operand" "ri,mr"))
627                  (const_int 0)))]
628   "ix86_match_ccmode (insn, CCGOCmode)"
629   "cmp{w}\t{%1, %0|%0, %1}"
630   [(set_attr "type" "icmp")
631    (set_attr "mode" "HI")])
633 (define_insn "*cmphi_1"
634   [(set (reg FLAGS_REG)
635         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
636                  (match_operand:HI 1 "general_operand" "ri,mr")))]
637   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
638    && ix86_match_ccmode (insn, CCmode)"
639   "cmp{w}\t{%1, %0|%0, %1}"
640   [(set_attr "type" "icmp")
641    (set_attr "mode" "HI")])
643 (define_insn "*cmpqi_ccno_1"
644   [(set (reg FLAGS_REG)
645         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
646                  (match_operand:QI 1 "const0_operand" "n,n")))]
647   "ix86_match_ccmode (insn, CCNOmode)"
648   "@
649    test{b}\t{%0, %0|%0, %0}
650    cmp{b}\t{$0, %0|%0, 0}"
651   [(set_attr "type" "test,icmp")
652    (set_attr "length_immediate" "0,1")
653    (set_attr "mode" "QI")])
655 (define_insn "*cmpqi_1"
656   [(set (reg FLAGS_REG)
657         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
658                  (match_operand:QI 1 "general_operand" "qi,mq")))]
659   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660     && ix86_match_ccmode (insn, CCmode)"
661   "cmp{b}\t{%1, %0|%0, %1}"
662   [(set_attr "type" "icmp")
663    (set_attr "mode" "QI")])
665 (define_insn "*cmpqi_minus_1"
666   [(set (reg FLAGS_REG)
667         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
668                            (match_operand:QI 1 "general_operand" "qi,mq"))
669                  (const_int 0)))]
670   "ix86_match_ccmode (insn, CCGOCmode)"
671   "cmp{b}\t{%1, %0|%0, %1}"
672   [(set_attr "type" "icmp")
673    (set_attr "mode" "QI")])
675 (define_insn "*cmpqi_ext_1"
676   [(set (reg FLAGS_REG)
677         (compare
678           (match_operand:QI 0 "general_operand" "Qm")
679           (subreg:QI
680             (zero_extract:SI
681               (match_operand 1 "ext_register_operand" "Q")
682               (const_int 8)
683               (const_int 8)) 0)))]
684   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
685   "cmp{b}\t{%h1, %0|%0, %h1}"
686   [(set_attr "type" "icmp")
687    (set_attr "mode" "QI")])
689 (define_insn "*cmpqi_ext_1_rex64"
690   [(set (reg FLAGS_REG)
691         (compare
692           (match_operand:QI 0 "register_operand" "Q")
693           (subreg:QI
694             (zero_extract:SI
695               (match_operand 1 "ext_register_operand" "Q")
696               (const_int 8)
697               (const_int 8)) 0)))]
698   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
699   "cmp{b}\t{%h1, %0|%0, %h1}"
700   [(set_attr "type" "icmp")
701    (set_attr "mode" "QI")])
703 (define_insn "*cmpqi_ext_2"
704   [(set (reg FLAGS_REG)
705         (compare
706           (subreg:QI
707             (zero_extract:SI
708               (match_operand 0 "ext_register_operand" "Q")
709               (const_int 8)
710               (const_int 8)) 0)
711           (match_operand:QI 1 "const0_operand" "n")))]
712   "ix86_match_ccmode (insn, CCNOmode)"
713   "test{b}\t%h0, %h0"
714   [(set_attr "type" "test")
715    (set_attr "length_immediate" "0")
716    (set_attr "mode" "QI")])
718 (define_expand "cmpqi_ext_3"
719   [(set (reg:CC FLAGS_REG)
720         (compare:CC
721           (subreg:QI
722             (zero_extract:SI
723               (match_operand 0 "ext_register_operand" "")
724               (const_int 8)
725               (const_int 8)) 0)
726           (match_operand:QI 1 "general_operand" "")))]
727   ""
728   "")
730 (define_insn "cmpqi_ext_3_insn"
731   [(set (reg FLAGS_REG)
732         (compare
733           (subreg:QI
734             (zero_extract:SI
735               (match_operand 0 "ext_register_operand" "Q")
736               (const_int 8)
737               (const_int 8)) 0)
738           (match_operand:QI 1 "general_operand" "Qmn")))]
739   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
740   "cmp{b}\t{%1, %h0|%h0, %1}"
741   [(set_attr "type" "icmp")
742    (set_attr "mode" "QI")])
744 (define_insn "cmpqi_ext_3_insn_rex64"
745   [(set (reg FLAGS_REG)
746         (compare
747           (subreg:QI
748             (zero_extract:SI
749               (match_operand 0 "ext_register_operand" "Q")
750               (const_int 8)
751               (const_int 8)) 0)
752           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
753   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
754   "cmp{b}\t{%1, %h0|%h0, %1}"
755   [(set_attr "type" "icmp")
756    (set_attr "mode" "QI")])
758 (define_insn "*cmpqi_ext_4"
759   [(set (reg FLAGS_REG)
760         (compare
761           (subreg:QI
762             (zero_extract:SI
763               (match_operand 0 "ext_register_operand" "Q")
764               (const_int 8)
765               (const_int 8)) 0)
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 1 "ext_register_operand" "Q")
769               (const_int 8)
770               (const_int 8)) 0)))]
771   "ix86_match_ccmode (insn, CCmode)"
772   "cmp{b}\t{%h1, %h0|%h0, %h1}"
773   [(set_attr "type" "icmp")
774    (set_attr "mode" "QI")])
776 ;; These implement float point compares.
777 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
778 ;; which would allow mix and match FP modes on the compares.  Which is what
779 ;; the old patterns did, but with many more of them.
781 (define_expand "cmpxf"
782   [(set (reg:CC FLAGS_REG)
783         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
784                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
785   "TARGET_80387"
787   ix86_compare_op0 = operands[0];
788   ix86_compare_op1 = operands[1];
789   DONE;
792 (define_expand "cmpdf"
793   [(set (reg:CC FLAGS_REG)
794         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
795                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
796   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
798   ix86_compare_op0 = operands[0];
799   ix86_compare_op1 = operands[1];
800   DONE;
803 (define_expand "cmpsf"
804   [(set (reg:CC FLAGS_REG)
805         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
806                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
807   "TARGET_80387 || TARGET_SSE_MATH"
809   ix86_compare_op0 = operands[0];
810   ix86_compare_op1 = operands[1];
811   DONE;
814 ;; FP compares, step 1:
815 ;; Set the FP condition codes.
817 ;; CCFPmode     compare with exceptions
818 ;; CCFPUmode    compare with no exceptions
820 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
821 ;; used to manage the reg stack popping would not be preserved.
823 (define_insn "*cmpfp_0"
824   [(set (match_operand:HI 0 "register_operand" "=a")
825         (unspec:HI
826           [(compare:CCFP
827              (match_operand 1 "register_operand" "f")
828              (match_operand 2 "const0_operand" "X"))]
829         UNSPEC_FNSTSW))]
830   "TARGET_80387
831    && FLOAT_MODE_P (GET_MODE (operands[1]))
832    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
833   "* return output_fp_compare (insn, operands, 0, 0);"
834   [(set_attr "type" "multi")
835    (set_attr "unit" "i387")
836    (set (attr "mode")
837      (cond [(match_operand:SF 1 "" "")
838               (const_string "SF")
839             (match_operand:DF 1 "" "")
840               (const_string "DF")
841            ]
842            (const_string "XF")))])
844 (define_insn "*cmpfp_sf"
845   [(set (match_operand:HI 0 "register_operand" "=a")
846         (unspec:HI
847           [(compare:CCFP
848              (match_operand:SF 1 "register_operand" "f")
849              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
850           UNSPEC_FNSTSW))]
851   "TARGET_80387"
852   "* return output_fp_compare (insn, operands, 0, 0);"
853   [(set_attr "type" "multi")
854    (set_attr "unit" "i387")
855    (set_attr "mode" "SF")])
857 (define_insn "*cmpfp_df"
858   [(set (match_operand:HI 0 "register_operand" "=a")
859         (unspec:HI
860           [(compare:CCFP
861              (match_operand:DF 1 "register_operand" "f")
862              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
863           UNSPEC_FNSTSW))]
864   "TARGET_80387"
865   "* return output_fp_compare (insn, operands, 0, 0);"
866   [(set_attr "type" "multi")
867    (set_attr "unit" "i387")
868    (set_attr "mode" "DF")])
870 (define_insn "*cmpfp_xf"
871   [(set (match_operand:HI 0 "register_operand" "=a")
872         (unspec:HI
873           [(compare:CCFP
874              (match_operand:XF 1 "register_operand" "f")
875              (match_operand:XF 2 "register_operand" "f"))]
876           UNSPEC_FNSTSW))]
877   "TARGET_80387"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "unit" "i387")
881    (set_attr "mode" "XF")])
883 (define_insn "*cmpfp_u"
884   [(set (match_operand:HI 0 "register_operand" "=a")
885         (unspec:HI
886           [(compare:CCFPU
887              (match_operand 1 "register_operand" "f")
888              (match_operand 2 "register_operand" "f"))]
889           UNSPEC_FNSTSW))]
890   "TARGET_80387
891    && FLOAT_MODE_P (GET_MODE (operands[1]))
892    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
893   "* return output_fp_compare (insn, operands, 0, 1);"
894   [(set_attr "type" "multi")
895    (set_attr "unit" "i387")
896    (set (attr "mode")
897      (cond [(match_operand:SF 1 "" "")
898               (const_string "SF")
899             (match_operand:DF 1 "" "")
900               (const_string "DF")
901            ]
902            (const_string "XF")))])
904 (define_insn "*cmpfp_<mode>"
905   [(set (match_operand:HI 0 "register_operand" "=a")
906         (unspec:HI
907           [(compare:CCFP
908              (match_operand 1 "register_operand" "f")
909              (match_operator 3 "float_operator"
910                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
911           UNSPEC_FNSTSW))]
912   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
913    && FLOAT_MODE_P (GET_MODE (operands[1]))
914    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
915   "* return output_fp_compare (insn, operands, 0, 0);"
916   [(set_attr "type" "multi")
917    (set_attr "unit" "i387")
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       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1178       return "mov{l}\t{%1, %0|%0, %1}";
1179     }
1181   [(set (attr "type")
1182      (cond [(eq_attr "alternative" "2")
1183               (const_string "mmx")
1184             (eq_attr "alternative" "3,4,5")
1185               (const_string "mmxmov")
1186             (eq_attr "alternative" "6")
1187               (const_string "sselog1")
1188             (eq_attr "alternative" "7,8,9,10,11")
1189               (const_string "ssemov")
1190             (and (ne (symbol_ref "flag_pic") (const_int 0))
1191                  (match_operand:SI 1 "symbolic_operand" ""))
1192               (const_string "lea")
1193            ]
1194            (const_string "imov")))
1195    (set (attr "mode")
1196      (cond [(eq_attr "alternative" "2,3")
1197               (const_string "DI")
1198             (eq_attr "alternative" "6,7")
1199               (if_then_else
1200                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1201                 (const_string "V4SF")
1202                 (const_string "TI"))
1203             (and (eq_attr "alternative" "8,9,10,11")
1204                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1205               (const_string "SF")
1206            ]
1207            (const_string "SI")))])
1209 ;; Stores and loads of ax to arbitrary constant address.
1210 ;; We fake an second form of instruction to force reload to load address
1211 ;; into register when rax is not available
1212 (define_insn "*movabssi_1_rex64"
1213   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1214         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1215   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1216   "@
1217    movabs{l}\t{%1, %P0|%P0, %1}
1218    mov{l}\t{%1, %a0|%a0, %1}"
1219   [(set_attr "type" "imov")
1220    (set_attr "modrm" "0,*")
1221    (set_attr "length_address" "8,0")
1222    (set_attr "length_immediate" "0,*")
1223    (set_attr "memory" "store")
1224    (set_attr "mode" "SI")])
1226 (define_insn "*movabssi_2_rex64"
1227   [(set (match_operand:SI 0 "register_operand" "=a,r")
1228         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1229   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1230   "@
1231    movabs{l}\t{%P1, %0|%0, %P1}
1232    mov{l}\t{%a1, %0|%0, %a1}"
1233   [(set_attr "type" "imov")
1234    (set_attr "modrm" "0,*")
1235    (set_attr "length_address" "8,0")
1236    (set_attr "length_immediate" "0")
1237    (set_attr "memory" "load")
1238    (set_attr "mode" "SI")])
1240 (define_insn "*swapsi"
1241   [(set (match_operand:SI 0 "register_operand" "+r")
1242         (match_operand:SI 1 "register_operand" "+r"))
1243    (set (match_dup 1)
1244         (match_dup 0))]
1245   ""
1246   "xchg{l}\t%1, %0"
1247   [(set_attr "type" "imov")
1248    (set_attr "mode" "SI")
1249    (set_attr "pent_pair" "np")
1250    (set_attr "athlon_decode" "vector")])
1252 (define_expand "movhi"
1253   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1254         (match_operand:HI 1 "general_operand" ""))]
1255   ""
1256   "ix86_expand_move (HImode, operands); DONE;")
1258 (define_insn "*pushhi2"
1259   [(set (match_operand:HI 0 "push_operand" "=<,<")
1260         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1261   "!TARGET_64BIT"
1262   "@
1263    push{w}\t{|WORD PTR }%1
1264    push{w}\t%1"
1265   [(set_attr "type" "push")
1266    (set_attr "mode" "HI")])
1268 ;; For 64BIT abi we always round up to 8 bytes.
1269 (define_insn "*pushhi2_rex64"
1270   [(set (match_operand:HI 0 "push_operand" "=X")
1271         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1272   "TARGET_64BIT"
1273   "push{q}\t%q1"
1274   [(set_attr "type" "push")
1275    (set_attr "mode" "QI")])
1277 (define_insn "*movhi_1"
1278   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1279         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1280   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1282   switch (get_attr_type (insn))
1283     {
1284     case TYPE_IMOVX:
1285       /* movzwl is faster than movw on p2 due to partial word stalls,
1286          though not as fast as an aligned movl.  */
1287       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1288     default:
1289       if (get_attr_mode (insn) == MODE_SI)
1290         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1291       else
1292         return "mov{w}\t{%1, %0|%0, %1}";
1293     }
1295   [(set (attr "type")
1296      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1297               (const_string "imov")
1298             (and (eq_attr "alternative" "0")
1299                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1300                           (const_int 0))
1301                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1302                           (const_int 0))))
1303               (const_string "imov")
1304             (and (eq_attr "alternative" "1,2")
1305                  (match_operand:HI 1 "aligned_operand" ""))
1306               (const_string "imov")
1307             (and (ne (symbol_ref "TARGET_MOVX")
1308                      (const_int 0))
1309                  (eq_attr "alternative" "0,2"))
1310               (const_string "imovx")
1311            ]
1312            (const_string "imov")))
1313     (set (attr "mode")
1314       (cond [(eq_attr "type" "imovx")
1315                (const_string "SI")
1316              (and (eq_attr "alternative" "1,2")
1317                   (match_operand:HI 1 "aligned_operand" ""))
1318                (const_string "SI")
1319              (and (eq_attr "alternative" "0")
1320                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1321                            (const_int 0))
1322                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1323                            (const_int 0))))
1324                (const_string "SI")
1325             ]
1326             (const_string "HI")))])
1328 ;; Stores and loads of ax to arbitrary constant address.
1329 ;; We fake an second form of instruction to force reload to load address
1330 ;; into register when rax is not available
1331 (define_insn "*movabshi_1_rex64"
1332   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1333         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1334   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1335   "@
1336    movabs{w}\t{%1, %P0|%P0, %1}
1337    mov{w}\t{%1, %a0|%a0, %1}"
1338   [(set_attr "type" "imov")
1339    (set_attr "modrm" "0,*")
1340    (set_attr "length_address" "8,0")
1341    (set_attr "length_immediate" "0,*")
1342    (set_attr "memory" "store")
1343    (set_attr "mode" "HI")])
1345 (define_insn "*movabshi_2_rex64"
1346   [(set (match_operand:HI 0 "register_operand" "=a,r")
1347         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1348   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1349   "@
1350    movabs{w}\t{%P1, %0|%0, %P1}
1351    mov{w}\t{%a1, %0|%0, %a1}"
1352   [(set_attr "type" "imov")
1353    (set_attr "modrm" "0,*")
1354    (set_attr "length_address" "8,0")
1355    (set_attr "length_immediate" "0")
1356    (set_attr "memory" "load")
1357    (set_attr "mode" "HI")])
1359 (define_insn "*swaphi_1"
1360   [(set (match_operand:HI 0 "register_operand" "+r")
1361         (match_operand:HI 1 "register_operand" "+r"))
1362    (set (match_dup 1)
1363         (match_dup 0))]
1364   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1365   "xchg{l}\t%k1, %k0"
1366   [(set_attr "type" "imov")
1367    (set_attr "mode" "SI")
1368    (set_attr "pent_pair" "np")
1369    (set_attr "athlon_decode" "vector")])
1371 (define_insn "*swaphi_2"
1372   [(set (match_operand:HI 0 "register_operand" "+r")
1373         (match_operand:HI 1 "register_operand" "+r"))
1374    (set (match_dup 1)
1375         (match_dup 0))]
1376   "TARGET_PARTIAL_REG_STALL"
1377   "xchg{w}\t%1, %0"
1378   [(set_attr "type" "imov")
1379    (set_attr "mode" "HI")
1380    (set_attr "pent_pair" "np")
1381    (set_attr "athlon_decode" "vector")])
1383 (define_expand "movstricthi"
1384   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1385         (match_operand:HI 1 "general_operand" ""))]
1386   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1388   /* Don't generate memory->memory moves, go through a register */
1389   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1390     operands[1] = force_reg (HImode, operands[1]);
1393 (define_insn "*movstricthi_1"
1394   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1395         (match_operand:HI 1 "general_operand" "rn,m"))]
1396   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1397    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1398   "mov{w}\t{%1, %0|%0, %1}"
1399   [(set_attr "type" "imov")
1400    (set_attr "mode" "HI")])
1402 (define_insn "*movstricthi_xor"
1403   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1404         (match_operand:HI 1 "const0_operand" "i"))
1405    (clobber (reg:CC FLAGS_REG))]
1406   "reload_completed
1407    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1408   "xor{w}\t{%0, %0|%0, %0}"
1409   [(set_attr "type" "alu1")
1410    (set_attr "mode" "HI")
1411    (set_attr "length_immediate" "0")])
1413 (define_expand "movqi"
1414   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1415         (match_operand:QI 1 "general_operand" ""))]
1416   ""
1417   "ix86_expand_move (QImode, operands); DONE;")
1419 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1420 ;; "push a byte".  But actually we use pushw, which has the effect
1421 ;; of rounding the amount pushed up to a halfword.
1423 (define_insn "*pushqi2"
1424   [(set (match_operand:QI 0 "push_operand" "=X,X")
1425         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1426   "!TARGET_64BIT"
1427   "@
1428    push{w}\t{|word ptr }%1
1429    push{w}\t%w1"
1430   [(set_attr "type" "push")
1431    (set_attr "mode" "HI")])
1433 ;; For 64BIT abi we always round up to 8 bytes.
1434 (define_insn "*pushqi2_rex64"
1435   [(set (match_operand:QI 0 "push_operand" "=X")
1436         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1437   "TARGET_64BIT"
1438   "push{q}\t%q1"
1439   [(set_attr "type" "push")
1440    (set_attr "mode" "QI")])
1442 ;; Situation is quite tricky about when to choose full sized (SImode) move
1443 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1444 ;; partial register dependency machines (such as AMD Athlon), where QImode
1445 ;; moves issue extra dependency and for partial register stalls machines
1446 ;; that don't use QImode patterns (and QImode move cause stall on the next
1447 ;; instruction).
1449 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1450 ;; register stall machines with, where we use QImode instructions, since
1451 ;; partial register stall can be caused there.  Then we use movzx.
1452 (define_insn "*movqi_1"
1453   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1454         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,m ,qn"))]
1455   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1457   switch (get_attr_type (insn))
1458     {
1459     case TYPE_IMOVX:
1460       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1461       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1462     default:
1463       if (get_attr_mode (insn) == MODE_SI)
1464         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1465       else
1466         return "mov{b}\t{%1, %0|%0, %1}";
1467     }
1469   [(set (attr "type")
1470      (cond [(eq_attr "alternative" "5")
1471               (const_string "imovx")
1472             (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")
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   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1521   if (! q_regs_operand (op1, QImode))
1522     {
1523       emit_insn (gen_movqi (op2, op1));
1524       op1 = op2;
1525     }
1526   emit_insn (gen_movqi (op0, op1));
1527   DONE;
1530 (define_insn "*swapqi_1"
1531   [(set (match_operand:QI 0 "register_operand" "+r")
1532         (match_operand:QI 1 "register_operand" "+r"))
1533    (set (match_dup 1)
1534         (match_dup 0))]
1535   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1536   "xchg{l}\t%k1, %k0"
1537   [(set_attr "type" "imov")
1538    (set_attr "mode" "SI")
1539    (set_attr "pent_pair" "np")
1540    (set_attr "athlon_decode" "vector")])
1542 (define_insn "*swapqi_2"
1543   [(set (match_operand:QI 0 "register_operand" "+q")
1544         (match_operand:QI 1 "register_operand" "+q"))
1545    (set (match_dup 1)
1546         (match_dup 0))]
1547   "TARGET_PARTIAL_REG_STALL"
1548   "xchg{b}\t%1, %0"
1549   [(set_attr "type" "imov")
1550    (set_attr "mode" "QI")
1551    (set_attr "pent_pair" "np")
1552    (set_attr "athlon_decode" "vector")])
1554 (define_expand "movstrictqi"
1555   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1556         (match_operand:QI 1 "general_operand" ""))]
1557   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1559   /* Don't generate memory->memory moves, go through a register.  */
1560   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1561     operands[1] = force_reg (QImode, operands[1]);
1564 (define_insn "*movstrictqi_1"
1565   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1566         (match_operand:QI 1 "general_operand" "*qn,m"))]
1567   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1568    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1569   "mov{b}\t{%1, %0|%0, %1}"
1570   [(set_attr "type" "imov")
1571    (set_attr "mode" "QI")])
1573 (define_insn "*movstrictqi_xor"
1574   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1575         (match_operand:QI 1 "const0_operand" "i"))
1576    (clobber (reg:CC FLAGS_REG))]
1577   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1578   "xor{b}\t{%0, %0|%0, %0}"
1579   [(set_attr "type" "alu1")
1580    (set_attr "mode" "QI")
1581    (set_attr "length_immediate" "0")])
1583 (define_insn "*movsi_extv_1"
1584   [(set (match_operand:SI 0 "register_operand" "=R")
1585         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1586                          (const_int 8)
1587                          (const_int 8)))]
1588   ""
1589   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1590   [(set_attr "type" "imovx")
1591    (set_attr "mode" "SI")])
1593 (define_insn "*movhi_extv_1"
1594   [(set (match_operand:HI 0 "register_operand" "=R")
1595         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1596                          (const_int 8)
1597                          (const_int 8)))]
1598   ""
1599   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1600   [(set_attr "type" "imovx")
1601    (set_attr "mode" "SI")])
1603 (define_insn "*movqi_extv_1"
1604   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1605         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1606                          (const_int 8)
1607                          (const_int 8)))]
1608   "!TARGET_64BIT"
1610   switch (get_attr_type (insn))
1611     {
1612     case TYPE_IMOVX:
1613       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1614     default:
1615       return "mov{b}\t{%h1, %0|%0, %h1}";
1616     }
1618   [(set (attr "type")
1619      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1620                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1621                              (ne (symbol_ref "TARGET_MOVX")
1622                                  (const_int 0))))
1623         (const_string "imovx")
1624         (const_string "imov")))
1625    (set (attr "mode")
1626      (if_then_else (eq_attr "type" "imovx")
1627         (const_string "SI")
1628         (const_string "QI")))])
1630 (define_insn "*movqi_extv_1_rex64"
1631   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1632         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1633                          (const_int 8)
1634                          (const_int 8)))]
1635   "TARGET_64BIT"
1637   switch (get_attr_type (insn))
1638     {
1639     case TYPE_IMOVX:
1640       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1641     default:
1642       return "mov{b}\t{%h1, %0|%0, %h1}";
1643     }
1645   [(set (attr "type")
1646      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1647                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1648                              (ne (symbol_ref "TARGET_MOVX")
1649                                  (const_int 0))))
1650         (const_string "imovx")
1651         (const_string "imov")))
1652    (set (attr "mode")
1653      (if_then_else (eq_attr "type" "imovx")
1654         (const_string "SI")
1655         (const_string "QI")))])
1657 ;; Stores and loads of ax to arbitrary constant address.
1658 ;; We fake an second form of instruction to force reload to load address
1659 ;; into register when rax is not available
1660 (define_insn "*movabsqi_1_rex64"
1661   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1662         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1663   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1664   "@
1665    movabs{b}\t{%1, %P0|%P0, %1}
1666    mov{b}\t{%1, %a0|%a0, %1}"
1667   [(set_attr "type" "imov")
1668    (set_attr "modrm" "0,*")
1669    (set_attr "length_address" "8,0")
1670    (set_attr "length_immediate" "0,*")
1671    (set_attr "memory" "store")
1672    (set_attr "mode" "QI")])
1674 (define_insn "*movabsqi_2_rex64"
1675   [(set (match_operand:QI 0 "register_operand" "=a,r")
1676         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1677   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1678   "@
1679    movabs{b}\t{%P1, %0|%0, %P1}
1680    mov{b}\t{%a1, %0|%0, %a1}"
1681   [(set_attr "type" "imov")
1682    (set_attr "modrm" "0,*")
1683    (set_attr "length_address" "8,0")
1684    (set_attr "length_immediate" "0")
1685    (set_attr "memory" "load")
1686    (set_attr "mode" "QI")])
1688 (define_insn "*movsi_extzv_1"
1689   [(set (match_operand:SI 0 "register_operand" "=R")
1690         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1691                          (const_int 8)
1692                          (const_int 8)))]
1693   ""
1694   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1695   [(set_attr "type" "imovx")
1696    (set_attr "mode" "SI")])
1698 (define_insn "*movqi_extzv_2"
1699   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1700         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1701                                     (const_int 8)
1702                                     (const_int 8)) 0))]
1703   "!TARGET_64BIT"
1705   switch (get_attr_type (insn))
1706     {
1707     case TYPE_IMOVX:
1708       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1709     default:
1710       return "mov{b}\t{%h1, %0|%0, %h1}";
1711     }
1713   [(set (attr "type")
1714      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1715                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1716                              (ne (symbol_ref "TARGET_MOVX")
1717                                  (const_int 0))))
1718         (const_string "imovx")
1719         (const_string "imov")))
1720    (set (attr "mode")
1721      (if_then_else (eq_attr "type" "imovx")
1722         (const_string "SI")
1723         (const_string "QI")))])
1725 (define_insn "*movqi_extzv_2_rex64"
1726   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1727         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1728                                     (const_int 8)
1729                                     (const_int 8)) 0))]
1730   "TARGET_64BIT"
1732   switch (get_attr_type (insn))
1733     {
1734     case TYPE_IMOVX:
1735       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1736     default:
1737       return "mov{b}\t{%h1, %0|%0, %h1}";
1738     }
1740   [(set (attr "type")
1741      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1742                         (ne (symbol_ref "TARGET_MOVX")
1743                             (const_int 0)))
1744         (const_string "imovx")
1745         (const_string "imov")))
1746    (set (attr "mode")
1747      (if_then_else (eq_attr "type" "imovx")
1748         (const_string "SI")
1749         (const_string "QI")))])
1751 (define_insn "movsi_insv_1"
1752   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1753                          (const_int 8)
1754                          (const_int 8))
1755         (match_operand:SI 1 "general_operand" "Qmn"))]
1756   "!TARGET_64BIT"
1757   "mov{b}\t{%b1, %h0|%h0, %b1}"
1758   [(set_attr "type" "imov")
1759    (set_attr "mode" "QI")])
1761 (define_insn "movdi_insv_1_rex64"
1762   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1763                          (const_int 8)
1764                          (const_int 8))
1765         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1766   "TARGET_64BIT"
1767   "mov{b}\t{%b1, %h0|%h0, %b1}"
1768   [(set_attr "type" "imov")
1769    (set_attr "mode" "QI")])
1771 (define_insn "*movqi_insv_2"
1772   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1773                          (const_int 8)
1774                          (const_int 8))
1775         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1776                      (const_int 8)))]
1777   ""
1778   "mov{b}\t{%h1, %h0|%h0, %h1}"
1779   [(set_attr "type" "imov")
1780    (set_attr "mode" "QI")])
1782 (define_expand "movdi"
1783   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1784         (match_operand:DI 1 "general_operand" ""))]
1785   ""
1786   "ix86_expand_move (DImode, operands); DONE;")
1788 (define_insn "*pushdi"
1789   [(set (match_operand:DI 0 "push_operand" "=<")
1790         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1791   "!TARGET_64BIT"
1792   "#")
1794 (define_insn "*pushdi2_rex64"
1795   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1796         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1797   "TARGET_64BIT"
1798   "@
1799    push{q}\t%1
1800    #"
1801   [(set_attr "type" "push,multi")
1802    (set_attr "mode" "DI")])
1804 ;; Convert impossible pushes of immediate to existing instructions.
1805 ;; First try to get scratch register and go through it.  In case this
1806 ;; fails, push sign extended lower part first and then overwrite
1807 ;; upper part by 32bit move.
1808 (define_peephole2
1809   [(match_scratch:DI 2 "r")
1810    (set (match_operand:DI 0 "push_operand" "")
1811         (match_operand:DI 1 "immediate_operand" ""))]
1812   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1813    && !x86_64_immediate_operand (operands[1], DImode)"
1814   [(set (match_dup 2) (match_dup 1))
1815    (set (match_dup 0) (match_dup 2))]
1816   "")
1818 ;; We need to define this as both peepholer and splitter for case
1819 ;; peephole2 pass is not run.
1820 ;; "&& 1" is needed to keep it from matching the previous pattern.
1821 (define_peephole2
1822   [(set (match_operand:DI 0 "push_operand" "")
1823         (match_operand:DI 1 "immediate_operand" ""))]
1824   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1825    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1826   [(set (match_dup 0) (match_dup 1))
1827    (set (match_dup 2) (match_dup 3))]
1828   "split_di (operands + 1, 1, operands + 2, operands + 3);
1829    operands[1] = gen_lowpart (DImode, operands[2]);
1830    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1831                                                     GEN_INT (4)));
1832   ")
1834 (define_split
1835   [(set (match_operand:DI 0 "push_operand" "")
1836         (match_operand:DI 1 "immediate_operand" ""))]
1837   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1838    && !symbolic_operand (operands[1], DImode)
1839    && !x86_64_immediate_operand (operands[1], DImode)"
1840   [(set (match_dup 0) (match_dup 1))
1841    (set (match_dup 2) (match_dup 3))]
1842   "split_di (operands + 1, 1, operands + 2, operands + 3);
1843    operands[1] = gen_lowpart (DImode, operands[2]);
1844    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1845                                                     GEN_INT (4)));
1846   ")
1848 (define_insn "*pushdi2_prologue_rex64"
1849   [(set (match_operand:DI 0 "push_operand" "=<")
1850         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1851    (clobber (mem:BLK (scratch)))]
1852   "TARGET_64BIT"
1853   "push{q}\t%1"
1854   [(set_attr "type" "push")
1855    (set_attr "mode" "DI")])
1857 (define_insn "*popdi1_epilogue_rex64"
1858   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1859         (mem:DI (reg:DI SP_REG)))
1860    (set (reg:DI SP_REG)
1861         (plus:DI (reg:DI SP_REG) (const_int 8)))
1862    (clobber (mem:BLK (scratch)))]
1863   "TARGET_64BIT"
1864   "pop{q}\t%0"
1865   [(set_attr "type" "pop")
1866    (set_attr "mode" "DI")])
1868 (define_insn "popdi1"
1869   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1870         (mem:DI (reg:DI SP_REG)))
1871    (set (reg:DI SP_REG)
1872         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1873   "TARGET_64BIT"
1874   "pop{q}\t%0"
1875   [(set_attr "type" "pop")
1876    (set_attr "mode" "DI")])
1878 (define_insn "*movdi_xor_rex64"
1879   [(set (match_operand:DI 0 "register_operand" "=r")
1880         (match_operand:DI 1 "const0_operand" "i"))
1881    (clobber (reg:CC FLAGS_REG))]
1882   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1883    && reload_completed"
1884   "xor{l}\t{%k0, %k0|%k0, %k0}"
1885   [(set_attr "type" "alu1")
1886    (set_attr "mode" "SI")
1887    (set_attr "length_immediate" "0")])
1889 (define_insn "*movdi_or_rex64"
1890   [(set (match_operand:DI 0 "register_operand" "=r")
1891         (match_operand:DI 1 "const_int_operand" "i"))
1892    (clobber (reg:CC FLAGS_REG))]
1893   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1894    && reload_completed
1895    && operands[1] == constm1_rtx"
1897   operands[1] = constm1_rtx;
1898   return "or{q}\t{%1, %0|%0, %1}";
1900   [(set_attr "type" "alu1")
1901    (set_attr "mode" "DI")
1902    (set_attr "length_immediate" "1")])
1904 (define_insn "*movdi_2"
1905   [(set (match_operand:DI 0 "nonimmediate_operand"
1906                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1907         (match_operand:DI 1 "general_operand"
1908                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1909   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1910   "@
1911    #
1912    #
1913    pxor\t%0, %0
1914    movq\t{%1, %0|%0, %1}
1915    movq\t{%1, %0|%0, %1}
1916    pxor\t%0, %0
1917    movq\t{%1, %0|%0, %1}
1918    movdqa\t{%1, %0|%0, %1}
1919    movq\t{%1, %0|%0, %1}
1920    xorps\t%0, %0
1921    movlps\t{%1, %0|%0, %1}
1922    movaps\t{%1, %0|%0, %1}
1923    movlps\t{%1, %0|%0, %1}"
1924   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1925    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1927 (define_split
1928   [(set (match_operand:DI 0 "push_operand" "")
1929         (match_operand:DI 1 "general_operand" ""))]
1930   "!TARGET_64BIT && reload_completed
1931    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1932   [(const_int 0)]
1933   "ix86_split_long_move (operands); DONE;")
1935 ;; %%% This multiword shite has got to go.
1936 (define_split
1937   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1938         (match_operand:DI 1 "general_operand" ""))]
1939   "!TARGET_64BIT && reload_completed
1940    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1941    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1942   [(const_int 0)]
1943   "ix86_split_long_move (operands); DONE;")
1945 (define_insn "*movdi_1_rex64"
1946   [(set (match_operand:DI 0 "nonimmediate_operand"
1947                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1948         (match_operand:DI 1 "general_operand"
1949                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1950   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1952   switch (get_attr_type (insn))
1953     {
1954     case TYPE_SSECVT:
1955       if (which_alternative == 13)
1956         return "movq2dq\t{%1, %0|%0, %1}";
1957       else
1958         return "movdq2q\t{%1, %0|%0, %1}";
1959     case TYPE_SSEMOV:
1960       if (get_attr_mode (insn) == MODE_TI)
1961           return "movdqa\t{%1, %0|%0, %1}";
1962       /* FALLTHRU */
1963     case TYPE_MMXMOV:
1964       /* Moves from and into integer register is done using movd opcode with
1965          REX prefix.  */
1966       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1967           return "movd\t{%1, %0|%0, %1}";
1968       return "movq\t{%1, %0|%0, %1}";
1969     case TYPE_SSELOG1:
1970     case TYPE_MMXADD:
1971       return "pxor\t%0, %0";
1972     case TYPE_MULTI:
1973       return "#";
1974     case TYPE_LEA:
1975       return "lea{q}\t{%a1, %0|%0, %a1}";
1976     default:
1977       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1978       if (get_attr_mode (insn) == MODE_SI)
1979         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1980       else if (which_alternative == 2)
1981         return "movabs{q}\t{%1, %0|%0, %1}";
1982       else
1983         return "mov{q}\t{%1, %0|%0, %1}";
1984     }
1986   [(set (attr "type")
1987      (cond [(eq_attr "alternative" "5")
1988               (const_string "mmx")
1989             (eq_attr "alternative" "6,7,8")
1990               (const_string "mmxmov")
1991             (eq_attr "alternative" "9")
1992               (const_string "sselog1")
1993             (eq_attr "alternative" "10,11,12")
1994               (const_string "ssemov")
1995             (eq_attr "alternative" "13,14")
1996               (const_string "ssecvt")
1997             (eq_attr "alternative" "4")
1998               (const_string "multi")
1999             (and (ne (symbol_ref "flag_pic") (const_int 0))
2000                  (match_operand:DI 1 "symbolic_operand" ""))
2001               (const_string "lea")
2002            ]
2003            (const_string "imov")))
2004    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2005    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2006    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2008 ;; Stores and loads of ax to arbitrary constant address.
2009 ;; We fake an second form of instruction to force reload to load address
2010 ;; into register when rax is not available
2011 (define_insn "*movabsdi_1_rex64"
2012   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2013         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2014   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2015   "@
2016    movabs{q}\t{%1, %P0|%P0, %1}
2017    mov{q}\t{%1, %a0|%a0, %1}"
2018   [(set_attr "type" "imov")
2019    (set_attr "modrm" "0,*")
2020    (set_attr "length_address" "8,0")
2021    (set_attr "length_immediate" "0,*")
2022    (set_attr "memory" "store")
2023    (set_attr "mode" "DI")])
2025 (define_insn "*movabsdi_2_rex64"
2026   [(set (match_operand:DI 0 "register_operand" "=a,r")
2027         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2028   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2029   "@
2030    movabs{q}\t{%P1, %0|%0, %P1}
2031    mov{q}\t{%a1, %0|%0, %a1}"
2032   [(set_attr "type" "imov")
2033    (set_attr "modrm" "0,*")
2034    (set_attr "length_address" "8,0")
2035    (set_attr "length_immediate" "0")
2036    (set_attr "memory" "load")
2037    (set_attr "mode" "DI")])
2039 ;; Convert impossible stores of immediate to existing instructions.
2040 ;; First try to get scratch register and go through it.  In case this
2041 ;; fails, move by 32bit parts.
2042 (define_peephole2
2043   [(match_scratch:DI 2 "r")
2044    (set (match_operand:DI 0 "memory_operand" "")
2045         (match_operand:DI 1 "immediate_operand" ""))]
2046   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2047    && !x86_64_immediate_operand (operands[1], DImode)"
2048   [(set (match_dup 2) (match_dup 1))
2049    (set (match_dup 0) (match_dup 2))]
2050   "")
2052 ;; We need to define this as both peepholer and splitter for case
2053 ;; peephole2 pass is not run.
2054 ;; "&& 1" is needed to keep it from matching the previous pattern.
2055 (define_peephole2
2056   [(set (match_operand:DI 0 "memory_operand" "")
2057         (match_operand:DI 1 "immediate_operand" ""))]
2058   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2059    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2060   [(set (match_dup 2) (match_dup 3))
2061    (set (match_dup 4) (match_dup 5))]
2062   "split_di (operands, 2, operands + 2, operands + 4);")
2064 (define_split
2065   [(set (match_operand:DI 0 "memory_operand" "")
2066         (match_operand:DI 1 "immediate_operand" ""))]
2067   "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2068    && !symbolic_operand (operands[1], DImode)
2069    && !x86_64_immediate_operand (operands[1], DImode)"
2070   [(set (match_dup 2) (match_dup 3))
2071    (set (match_dup 4) (match_dup 5))]
2072   "split_di (operands, 2, operands + 2, operands + 4);")
2074 (define_insn "*swapdi_rex64"
2075   [(set (match_operand:DI 0 "register_operand" "+r")
2076         (match_operand:DI 1 "register_operand" "+r"))
2077    (set (match_dup 1)
2078         (match_dup 0))]
2079   "TARGET_64BIT"
2080   "xchg{q}\t%1, %0"
2081   [(set_attr "type" "imov")
2082    (set_attr "mode" "DI")
2083    (set_attr "pent_pair" "np")
2084    (set_attr "athlon_decode" "vector")])
2086 (define_expand "movti"
2087   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2088         (match_operand:TI 1 "nonimmediate_operand" ""))]
2089   "TARGET_SSE || TARGET_64BIT"
2091   if (TARGET_64BIT)
2092     ix86_expand_move (TImode, operands);
2093   else
2094     ix86_expand_vector_move (TImode, operands);
2095   DONE;
2098 (define_insn "*movti_internal"
2099   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2100         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2101   "TARGET_SSE && !TARGET_64BIT
2102    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2104   switch (which_alternative)
2105     {
2106     case 0:
2107       if (get_attr_mode (insn) == MODE_V4SF)
2108         return "xorps\t%0, %0";
2109       else
2110         return "pxor\t%0, %0";
2111     case 1:
2112     case 2:
2113       if (get_attr_mode (insn) == MODE_V4SF)
2114         return "movaps\t{%1, %0|%0, %1}";
2115       else
2116         return "movdqa\t{%1, %0|%0, %1}";
2117     default:
2118       gcc_unreachable ();
2119     }
2121   [(set_attr "type" "ssemov,ssemov,ssemov")
2122    (set (attr "mode")
2123         (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2124                  (const_string "V4SF")
2126                (eq_attr "alternative" "0,1")
2127                  (if_then_else
2128                    (ne (symbol_ref "optimize_size")
2129                        (const_int 0))
2130                    (const_string "V4SF")
2131                    (const_string "TI"))
2132                (eq_attr "alternative" "2")
2133                  (if_then_else
2134                    (ne (symbol_ref "optimize_size")
2135                        (const_int 0))
2136                    (const_string "V4SF")
2137                    (const_string "TI"))]
2138                (const_string "TI")))])
2140 (define_insn "*movti_rex64"
2141   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2142         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2143   "TARGET_64BIT
2144    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2146   switch (which_alternative)
2147     {
2148     case 0:
2149     case 1:
2150       return "#";
2151     case 2:
2152       if (get_attr_mode (insn) == MODE_V4SF)
2153         return "xorps\t%0, %0";
2154       else
2155         return "pxor\t%0, %0";
2156     case 3:
2157     case 4:
2158       if (get_attr_mode (insn) == MODE_V4SF)
2159         return "movaps\t{%1, %0|%0, %1}";
2160       else
2161         return "movdqa\t{%1, %0|%0, %1}";
2162     default:
2163       gcc_unreachable ();
2164     }
2166   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2167    (set (attr "mode")
2168         (cond [(eq_attr "alternative" "2,3")
2169                  (if_then_else
2170                    (ne (symbol_ref "optimize_size")
2171                        (const_int 0))
2172                    (const_string "V4SF")
2173                    (const_string "TI"))
2174                (eq_attr "alternative" "4")
2175                  (if_then_else
2176                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2177                             (const_int 0))
2178                         (ne (symbol_ref "optimize_size")
2179                             (const_int 0)))
2180                    (const_string "V4SF")
2181                    (const_string "TI"))]
2182                (const_string "DI")))])
2184 (define_split
2185   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2186         (match_operand:TI 1 "general_operand" ""))]
2187   "reload_completed && !SSE_REG_P (operands[0])
2188    && !SSE_REG_P (operands[1])"
2189   [(const_int 0)]
2190   "ix86_split_long_move (operands); DONE;")
2192 (define_expand "movsf"
2193   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2194         (match_operand:SF 1 "general_operand" ""))]
2195   ""
2196   "ix86_expand_move (SFmode, operands); DONE;")
2198 (define_insn "*pushsf"
2199   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2200         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2201   "!TARGET_64BIT"
2203   /* Anything else should be already split before reg-stack.  */
2204   gcc_assert (which_alternative == 1);
2205   return "push{l}\t%1";
2207   [(set_attr "type" "multi,push,multi")
2208    (set_attr "unit" "i387,*,*")
2209    (set_attr "mode" "SF,SI,SF")])
2211 (define_insn "*pushsf_rex64"
2212   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2213         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2214   "TARGET_64BIT"
2216   /* Anything else should be already split before reg-stack.  */
2217   gcc_assert (which_alternative == 1);
2218   return "push{q}\t%q1";
2220   [(set_attr "type" "multi,push,multi")
2221    (set_attr "unit" "i387,*,*")
2222    (set_attr "mode" "SF,DI,SF")])
2224 (define_split
2225   [(set (match_operand:SF 0 "push_operand" "")
2226         (match_operand:SF 1 "memory_operand" ""))]
2227   "reload_completed
2228    && GET_CODE (operands[1]) == MEM
2229    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2230    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2231   [(set (match_dup 0)
2232         (match_dup 1))]
2233   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2236 ;; %%% Kill this when call knows how to work this out.
2237 (define_split
2238   [(set (match_operand:SF 0 "push_operand" "")
2239         (match_operand:SF 1 "any_fp_register_operand" ""))]
2240   "!TARGET_64BIT"
2241   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2242    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2244 (define_split
2245   [(set (match_operand:SF 0 "push_operand" "")
2246         (match_operand:SF 1 "any_fp_register_operand" ""))]
2247   "TARGET_64BIT"
2248   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2249    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2251 (define_insn "*movsf_1"
2252   [(set (match_operand:SF 0 "nonimmediate_operand"
2253           "=f#xr,m   ,f#xr,r#xf  ,m    ,x#rf,x#rf,x#rf ,m   ,!*y,!rm,!*y")
2254         (match_operand:SF 1 "general_operand"
2255           "fm#rx,f#rx,G   ,rmF#fx,Fr#fx,C   ,x   ,xm#rf,x#rf,rm ,*y ,*y"))]
2256   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2257    && (reload_in_progress || reload_completed
2258        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2259        || GET_CODE (operands[1]) != CONST_DOUBLE
2260        || memory_operand (operands[0], SFmode))" 
2262   switch (which_alternative)
2263     {
2264     case 0:
2265       return output_387_reg_move (insn, operands);
2267     case 1:
2268       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2269         return "fstp%z0\t%y0";
2270       else
2271         return "fst%z0\t%y0";
2273     case 2:
2274       return standard_80387_constant_opcode (operands[1]);
2276     case 3:
2277     case 4:
2278       return "mov{l}\t{%1, %0|%0, %1}";
2279     case 5:
2280       if (get_attr_mode (insn) == MODE_TI)
2281         return "pxor\t%0, %0";
2282       else
2283         return "xorps\t%0, %0";
2284     case 6:
2285       if (get_attr_mode (insn) == MODE_V4SF)
2286         return "movaps\t{%1, %0|%0, %1}";
2287       else
2288         return "movss\t{%1, %0|%0, %1}";
2289     case 7:
2290     case 8:
2291       return "movss\t{%1, %0|%0, %1}";
2293     case 9:
2294     case 10:
2295       return "movd\t{%1, %0|%0, %1}";
2297     case 11:
2298       return "movq\t{%1, %0|%0, %1}";
2300     default:
2301       gcc_unreachable ();
2302     }
2304   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2305    (set (attr "mode")
2306         (cond [(eq_attr "alternative" "3,4,9,10")
2307                  (const_string "SI")
2308                (eq_attr "alternative" "5")
2309                  (if_then_else
2310                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2311                                  (const_int 0))
2312                              (ne (symbol_ref "TARGET_SSE2")
2313                                  (const_int 0)))
2314                         (eq (symbol_ref "optimize_size")
2315                             (const_int 0)))
2316                    (const_string "TI")
2317                    (const_string "V4SF"))
2318                /* For architectures resolving dependencies on
2319                   whole SSE registers use APS move to break dependency
2320                   chains, otherwise use short move to avoid extra work. 
2322                   Do the same for architectures resolving dependencies on
2323                   the parts.  While in DF mode it is better to always handle
2324                   just register parts, the SF mode is different due to lack
2325                   of instructions to load just part of the register.  It is
2326                   better to maintain the whole registers in single format
2327                   to avoid problems on using packed logical operations.  */
2328                (eq_attr "alternative" "6")
2329                  (if_then_else
2330                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2331                             (const_int 0))
2332                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2333                             (const_int 0)))
2334                    (const_string "V4SF")
2335                    (const_string "SF"))
2336                (eq_attr "alternative" "11")
2337                  (const_string "DI")]
2338                (const_string "SF")))])
2340 (define_insn "*swapsf"
2341   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2342         (match_operand:SF 1 "fp_register_operand" "+f"))
2343    (set (match_dup 1)
2344         (match_dup 0))]
2345   "reload_completed || TARGET_80387"
2347   if (STACK_TOP_P (operands[0]))
2348     return "fxch\t%1";
2349   else
2350     return "fxch\t%0";
2352   [(set_attr "type" "fxch")
2353    (set_attr "mode" "SF")])
2355 (define_expand "movdf"
2356   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2357         (match_operand:DF 1 "general_operand" ""))]
2358   ""
2359   "ix86_expand_move (DFmode, operands); DONE;")
2361 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2362 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2363 ;; On the average, pushdf using integers can be still shorter.  Allow this
2364 ;; pattern for optimize_size too.
2366 (define_insn "*pushdf_nointeger"
2367   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2368         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2369   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2371   /* This insn should be already split before reg-stack.  */
2372   gcc_unreachable ();
2374   [(set_attr "type" "multi")
2375    (set_attr "unit" "i387,*,*,*")
2376    (set_attr "mode" "DF,SI,SI,DF")])
2378 (define_insn "*pushdf_integer"
2379   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2380         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2381   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2383   /* This insn should be already split before reg-stack.  */
2384   gcc_unreachable ();
2386   [(set_attr "type" "multi")
2387    (set_attr "unit" "i387,*,*")
2388    (set_attr "mode" "DF,SI,DF")])
2390 ;; %%% Kill this when call knows how to work this out.
2391 (define_split
2392   [(set (match_operand:DF 0 "push_operand" "")
2393         (match_operand:DF 1 "any_fp_register_operand" ""))]
2394   "!TARGET_64BIT && reload_completed"
2395   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2396    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2397   "")
2399 (define_split
2400   [(set (match_operand:DF 0 "push_operand" "")
2401         (match_operand:DF 1 "any_fp_register_operand" ""))]
2402   "TARGET_64BIT && reload_completed"
2403   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2404    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2405   "")
2407 (define_split
2408   [(set (match_operand:DF 0 "push_operand" "")
2409         (match_operand:DF 1 "general_operand" ""))]
2410   "reload_completed"
2411   [(const_int 0)]
2412   "ix86_split_long_move (operands); DONE;")
2414 ;; Moving is usually shorter when only FP registers are used. This separate
2415 ;; movdf pattern avoids the use of integer registers for FP operations
2416 ;; when optimizing for size.
2418 (define_insn "*movdf_nointeger"
2419   [(set (match_operand:DF 0 "nonimmediate_operand"
2420                         "=f#Y,m  ,f#Y,*r  ,o  ,Y*x#f,Y*x#f,Y*x#f  ,m    ")
2421         (match_operand:DF 1 "general_operand"
2422                         "fm#Y,f#Y,G  ,*roF,F*r,C    ,Y*x#f,HmY*x#f,Y*x#f"))]
2423   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2424    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2425    && (reload_in_progress || reload_completed
2426        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2427        || GET_CODE (operands[1]) != CONST_DOUBLE
2428        || memory_operand (operands[0], DFmode))" 
2430   switch (which_alternative)
2431     {
2432     case 0:
2433       return output_387_reg_move (insn, operands);
2435     case 1:
2436       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2437         return "fstp%z0\t%y0";
2438       else
2439         return "fst%z0\t%y0";
2441     case 2:
2442       return standard_80387_constant_opcode (operands[1]);
2444     case 3:
2445     case 4:
2446       return "#";
2447     case 5:
2448       switch (get_attr_mode (insn))
2449         {
2450         case MODE_V4SF:
2451           return "xorps\t%0, %0";
2452         case MODE_V2DF:
2453           return "xorpd\t%0, %0";
2454         case MODE_TI:
2455           return "pxor\t%0, %0";
2456         default:
2457           gcc_unreachable ();
2458         }
2459     case 6:
2460     case 7:
2461     case 8:
2462       switch (get_attr_mode (insn))
2463         {
2464         case MODE_V4SF:
2465           return "movaps\t{%1, %0|%0, %1}";
2466         case MODE_V2DF:
2467           return "movapd\t{%1, %0|%0, %1}";
2468         case MODE_TI:
2469           return "movdqa\t{%1, %0|%0, %1}";
2470         case MODE_DI:
2471           return "movq\t{%1, %0|%0, %1}";
2472         case MODE_DF:
2473           return "movsd\t{%1, %0|%0, %1}";
2474         case MODE_V1DF:
2475           return "movlpd\t{%1, %0|%0, %1}";
2476         case MODE_V2SF:
2477           return "movlps\t{%1, %0|%0, %1}";
2478         default:
2479           gcc_unreachable ();
2480         }
2482     default:
2483       gcc_unreachable ();
2484     }
2486   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2487    (set (attr "mode")
2488         (cond [(eq_attr "alternative" "0,1,2")
2489                  (const_string "DF")
2490                (eq_attr "alternative" "3,4")
2491                  (const_string "SI")
2493                /* For SSE1, we have many fewer alternatives.  */
2494                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2495                  (cond [(eq_attr "alternative" "5,6")
2496                           (const_string "V4SF")
2497                        ]
2498                    (const_string "V2SF"))
2500                /* xorps is one byte shorter.  */
2501                (eq_attr "alternative" "5")
2502                  (cond [(ne (symbol_ref "optimize_size")
2503                             (const_int 0))
2504                           (const_string "V4SF")
2505                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2506                             (const_int 0))
2507                           (const_string "TI")
2508                        ]
2509                        (const_string "V2DF"))
2511                /* For architectures resolving dependencies on
2512                   whole SSE registers use APD move to break dependency
2513                   chains, otherwise use short move to avoid extra work.
2515                   movaps encodes one byte shorter.  */
2516                (eq_attr "alternative" "6")
2517                  (cond
2518                    [(ne (symbol_ref "optimize_size")
2519                         (const_int 0))
2520                       (const_string "V4SF")
2521                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2522                         (const_int 0))
2523                       (const_string "V2DF")
2524                    ]
2525                    (const_string "DF"))
2526                /* For architectures resolving dependencies on register
2527                   parts we may avoid extra work to zero out upper part
2528                   of register.  */
2529                (eq_attr "alternative" "7")
2530                  (if_then_else
2531                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2532                        (const_int 0))
2533                    (const_string "V1DF")
2534                    (const_string "DF"))
2535               ]
2536               (const_string "DF")))])
2538 (define_insn "*movdf_integer"
2539   [(set (match_operand:DF 0 "nonimmediate_operand"
2540                 "=f#Yr,m   ,f#Yr,r#Yf  ,o    ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2541         (match_operand:DF 1 "general_operand"
2542                 "fm#Yr,f#Yr,G   ,roF#Yf,Fr#Yf,C     ,Y*x#rf,m     ,Y*x#rf"))]
2543   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2544    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2545    && (reload_in_progress || reload_completed
2546        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2547        || GET_CODE (operands[1]) != CONST_DOUBLE
2548        || memory_operand (operands[0], DFmode))" 
2550   switch (which_alternative)
2551     {
2552     case 0:
2553       return output_387_reg_move (insn, operands);
2555     case 1:
2556       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2557         return "fstp%z0\t%y0";
2558       else
2559         return "fst%z0\t%y0";
2561     case 2:
2562       return standard_80387_constant_opcode (operands[1]);
2564     case 3:
2565     case 4:
2566       return "#";
2568     case 5:
2569       switch (get_attr_mode (insn))
2570         {
2571         case MODE_V4SF:
2572           return "xorps\t%0, %0";
2573         case MODE_V2DF:
2574           return "xorpd\t%0, %0";
2575         case MODE_TI:
2576           return "pxor\t%0, %0";
2577         default:
2578           gcc_unreachable ();
2579         }
2580     case 6:
2581     case 7:
2582     case 8:
2583       switch (get_attr_mode (insn))
2584         {
2585         case MODE_V4SF:
2586           return "movaps\t{%1, %0|%0, %1}";
2587         case MODE_V2DF:
2588           return "movapd\t{%1, %0|%0, %1}";
2589         case MODE_TI:
2590           return "movdqa\t{%1, %0|%0, %1}";
2591         case MODE_DI:
2592           return "movq\t{%1, %0|%0, %1}";
2593         case MODE_DF:
2594           return "movsd\t{%1, %0|%0, %1}";
2595         case MODE_V1DF:
2596           return "movlpd\t{%1, %0|%0, %1}";
2597         case MODE_V2SF:
2598           return "movlps\t{%1, %0|%0, %1}";
2599         default:
2600           gcc_unreachable ();
2601         }
2603     default:
2604       gcc_unreachable();
2605     }
2607   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2608    (set (attr "mode")
2609         (cond [(eq_attr "alternative" "0,1,2")
2610                  (const_string "DF")
2611                (eq_attr "alternative" "3,4")
2612                  (const_string "SI")
2614                /* For SSE1, we have many fewer alternatives.  */
2615                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2616                  (cond [(eq_attr "alternative" "5,6")
2617                           (const_string "V4SF")
2618                        ]
2619                    (const_string "V2SF"))
2621                /* xorps is one byte shorter.  */
2622                (eq_attr "alternative" "5")
2623                  (cond [(ne (symbol_ref "optimize_size")
2624                             (const_int 0))
2625                           (const_string "V4SF")
2626                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2627                             (const_int 0))
2628                           (const_string "TI")
2629                        ]
2630                        (const_string "V2DF"))
2632                /* For architectures resolving dependencies on
2633                   whole SSE registers use APD move to break dependency
2634                   chains, otherwise use short move to avoid extra work.
2636                   movaps encodes one byte shorter.  */
2637                (eq_attr "alternative" "6")
2638                  (cond
2639                    [(ne (symbol_ref "optimize_size")
2640                         (const_int 0))
2641                       (const_string "V4SF")
2642                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2643                         (const_int 0))
2644                       (const_string "V2DF")
2645                    ]
2646                    (const_string "DF"))
2647                /* For architectures resolving dependencies on register
2648                   parts we may avoid extra work to zero out upper part
2649                   of register.  */
2650                (eq_attr "alternative" "7")
2651                  (if_then_else
2652                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2653                        (const_int 0))
2654                    (const_string "V1DF")
2655                    (const_string "DF"))
2656               ]
2657               (const_string "DF")))])
2659 (define_split
2660   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2661         (match_operand:DF 1 "general_operand" ""))]
2662   "reload_completed
2663    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2664    && ! (ANY_FP_REG_P (operands[0]) || 
2665          (GET_CODE (operands[0]) == SUBREG
2666           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2667    && ! (ANY_FP_REG_P (operands[1]) || 
2668          (GET_CODE (operands[1]) == SUBREG
2669           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2670   [(const_int 0)]
2671   "ix86_split_long_move (operands); DONE;")
2673 (define_insn "*swapdf"
2674   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2675         (match_operand:DF 1 "fp_register_operand" "+f"))
2676    (set (match_dup 1)
2677         (match_dup 0))]
2678   "reload_completed || TARGET_80387"
2680   if (STACK_TOP_P (operands[0]))
2681     return "fxch\t%1";
2682   else
2683     return "fxch\t%0";
2685   [(set_attr "type" "fxch")
2686    (set_attr "mode" "DF")])
2688 (define_expand "movxf"
2689   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2690         (match_operand:XF 1 "general_operand" ""))]
2691   ""
2692   "ix86_expand_move (XFmode, operands); DONE;")
2694 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2695 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2696 ;; Pushing using integer instructions is longer except for constants
2697 ;; and direct memory references.
2698 ;; (assuming that any given constant is pushed only once, but this ought to be
2699 ;;  handled elsewhere).
2701 (define_insn "*pushxf_nointeger"
2702   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2703         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2704   "optimize_size"
2706   /* This insn should be already split before reg-stack.  */
2707   gcc_unreachable ();
2709   [(set_attr "type" "multi")
2710    (set_attr "unit" "i387,*,*")
2711    (set_attr "mode" "XF,SI,SI")])
2713 (define_insn "*pushxf_integer"
2714   [(set (match_operand:XF 0 "push_operand" "=<,<")
2715         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2716   "!optimize_size"
2718   /* This insn should be already split before reg-stack.  */
2719   gcc_unreachable ();
2721   [(set_attr "type" "multi")
2722    (set_attr "unit" "i387,*")
2723    (set_attr "mode" "XF,SI")])
2725 (define_split
2726   [(set (match_operand 0 "push_operand" "")
2727         (match_operand 1 "general_operand" ""))]
2728   "reload_completed
2729    && (GET_MODE (operands[0]) == XFmode
2730        || GET_MODE (operands[0]) == DFmode)
2731    && !ANY_FP_REG_P (operands[1])"
2732   [(const_int 0)]
2733   "ix86_split_long_move (operands); DONE;")
2735 (define_split
2736   [(set (match_operand:XF 0 "push_operand" "")
2737         (match_operand:XF 1 "any_fp_register_operand" ""))]
2738   "!TARGET_64BIT"
2739   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2740    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2741   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
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:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2748    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2749   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2751 ;; Do not use integer registers when optimizing for size
2752 (define_insn "*movxf_nointeger"
2753   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2754         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2755   "optimize_size
2756    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2757    && (reload_in_progress || reload_completed
2758        || GET_CODE (operands[1]) != CONST_DOUBLE
2759        || memory_operand (operands[0], XFmode))" 
2761   switch (which_alternative)
2762     {
2763     case 0:
2764       return output_387_reg_move (insn, operands);
2766     case 1:
2767       /* There is no non-popping store to memory for XFmode.  So if
2768          we need one, follow the store with a load.  */
2769       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2770         return "fstp%z0\t%y0\;fld%z0\t%y0";
2771       else
2772         return "fstp%z0\t%y0";
2774     case 2:
2775       return standard_80387_constant_opcode (operands[1]);
2777     case 3: case 4:
2778       return "#";
2779     default:
2780       gcc_unreachable ();
2781     }
2783   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2784    (set_attr "mode" "XF,XF,XF,SI,SI")])
2786 (define_insn "*movxf_integer"
2787   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2788         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2789   "!optimize_size
2790    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2791    && (reload_in_progress || reload_completed
2792        || GET_CODE (operands[1]) != CONST_DOUBLE
2793        || memory_operand (operands[0], XFmode))" 
2795   switch (which_alternative)
2796     {
2797     case 0:
2798       return output_387_reg_move (insn, operands);
2800     case 1:
2801       /* There is no non-popping store to memory for XFmode.  So if
2802          we need one, follow the store with a load.  */
2803       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2804         return "fstp%z0\t%y0\;fld%z0\t%y0";
2805       else
2806         return "fstp%z0\t%y0";
2808     case 2:
2809       return standard_80387_constant_opcode (operands[1]);
2811     case 3: case 4:
2812       return "#";
2814     default:
2815       gcc_unreachable ();
2816     }
2818   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2819    (set_attr "mode" "XF,XF,XF,SI,SI")])
2821 (define_split
2822   [(set (match_operand 0 "nonimmediate_operand" "")
2823         (match_operand 1 "general_operand" ""))]
2824   "reload_completed
2825    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2826    && GET_MODE (operands[0]) == XFmode
2827    && ! (ANY_FP_REG_P (operands[0]) || 
2828          (GET_CODE (operands[0]) == SUBREG
2829           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2830    && ! (ANY_FP_REG_P (operands[1]) || 
2831          (GET_CODE (operands[1]) == SUBREG
2832           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2833   [(const_int 0)]
2834   "ix86_split_long_move (operands); DONE;")
2836 (define_split
2837   [(set (match_operand 0 "register_operand" "")
2838         (match_operand 1 "memory_operand" ""))]
2839   "reload_completed
2840    && GET_CODE (operands[1]) == MEM
2841    && (GET_MODE (operands[0]) == XFmode
2842        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2843    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2844    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2845   [(set (match_dup 0) (match_dup 1))]
2847   rtx c = get_pool_constant (XEXP (operands[1], 0));
2848   rtx r = operands[0];
2850   if (GET_CODE (r) == SUBREG)
2851     r = SUBREG_REG (r);
2853   if (SSE_REG_P (r))
2854     {
2855       if (!standard_sse_constant_p (c))
2856         FAIL;
2857     }
2858   else if (FP_REG_P (r))
2859     {
2860       if (!standard_80387_constant_p (c))
2861         FAIL;
2862     }
2863   else if (MMX_REG_P (r))
2864     FAIL;
2866   operands[1] = c;
2869 (define_insn "swapxf"
2870   [(set (match_operand:XF 0 "register_operand" "+f")
2871         (match_operand:XF 1 "register_operand" "+f"))
2872    (set (match_dup 1)
2873         (match_dup 0))]
2874   "TARGET_80387"
2876   if (STACK_TOP_P (operands[0]))
2877     return "fxch\t%1";
2878   else
2879     return "fxch\t%0";
2881   [(set_attr "type" "fxch")
2882    (set_attr "mode" "XF")])
2884 (define_expand "movtf"
2885   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2886         (match_operand:TF 1 "nonimmediate_operand" ""))]
2887   "TARGET_64BIT"
2889   ix86_expand_move (TFmode, operands);
2890   DONE;
2893 (define_insn "*movtf_internal"
2894   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2895         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2896   "TARGET_64BIT
2897    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2899   switch (which_alternative)
2900     {
2901     case 0:
2902     case 1:
2903       return "#";
2904     case 2:
2905       if (get_attr_mode (insn) == MODE_V4SF)
2906         return "xorps\t%0, %0";
2907       else
2908         return "pxor\t%0, %0";
2909     case 3:
2910     case 4:
2911       if (get_attr_mode (insn) == MODE_V4SF)
2912         return "movaps\t{%1, %0|%0, %1}";
2913       else
2914         return "movdqa\t{%1, %0|%0, %1}";
2915     default:
2916       gcc_unreachable ();
2917     }
2919   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2920    (set (attr "mode")
2921         (cond [(eq_attr "alternative" "2,3")
2922                  (if_then_else
2923                    (ne (symbol_ref "optimize_size")
2924                        (const_int 0))
2925                    (const_string "V4SF")
2926                    (const_string "TI"))
2927                (eq_attr "alternative" "4")
2928                  (if_then_else
2929                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2930                             (const_int 0))
2931                         (ne (symbol_ref "optimize_size")
2932                             (const_int 0)))
2933                    (const_string "V4SF")
2934                    (const_string "TI"))]
2935                (const_string "DI")))])
2937 (define_split
2938   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2939         (match_operand:TF 1 "general_operand" ""))]
2940   "reload_completed && !SSE_REG_P (operands[0])
2941    && !SSE_REG_P (operands[1])"
2942   [(const_int 0)]
2943   "ix86_split_long_move (operands); DONE;")
2945 ;; Zero extension instructions
2947 (define_expand "zero_extendhisi2"
2948   [(set (match_operand:SI 0 "register_operand" "")
2949      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2950   ""
2952   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2953     {
2954       operands[1] = force_reg (HImode, operands[1]);
2955       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2956       DONE;
2957     }
2960 (define_insn "zero_extendhisi2_and"
2961   [(set (match_operand:SI 0 "register_operand" "=r")
2962      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2963    (clobber (reg:CC FLAGS_REG))]
2964   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2965   "#"
2966   [(set_attr "type" "alu1")
2967    (set_attr "mode" "SI")])
2969 (define_split
2970   [(set (match_operand:SI 0 "register_operand" "")
2971         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2972    (clobber (reg:CC FLAGS_REG))]
2973   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2974   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2975               (clobber (reg:CC FLAGS_REG))])]
2976   "")
2978 (define_insn "*zero_extendhisi2_movzwl"
2979   [(set (match_operand:SI 0 "register_operand" "=r")
2980      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2981   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2982   "movz{wl|x}\t{%1, %0|%0, %1}"
2983   [(set_attr "type" "imovx")
2984    (set_attr "mode" "SI")])
2986 (define_expand "zero_extendqihi2"
2987   [(parallel
2988     [(set (match_operand:HI 0 "register_operand" "")
2989        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2990      (clobber (reg:CC FLAGS_REG))])]
2991   ""
2992   "")
2994 (define_insn "*zero_extendqihi2_and"
2995   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2996      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2997    (clobber (reg:CC FLAGS_REG))]
2998   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2999   "#"
3000   [(set_attr "type" "alu1")
3001    (set_attr "mode" "HI")])
3003 (define_insn "*zero_extendqihi2_movzbw_and"
3004   [(set (match_operand:HI 0 "register_operand" "=r,r")
3005      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3006    (clobber (reg:CC FLAGS_REG))]
3007   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3008   "#"
3009   [(set_attr "type" "imovx,alu1")
3010    (set_attr "mode" "HI")])
3012 (define_insn "*zero_extendqihi2_movzbw"
3013   [(set (match_operand:HI 0 "register_operand" "=r")
3014      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3015   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3016   "movz{bw|x}\t{%1, %0|%0, %1}"
3017   [(set_attr "type" "imovx")
3018    (set_attr "mode" "HI")])
3020 ;; For the movzbw case strip only the clobber
3021 (define_split
3022   [(set (match_operand:HI 0 "register_operand" "")
3023         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3024    (clobber (reg:CC FLAGS_REG))]
3025   "reload_completed 
3026    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3027    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3028   [(set (match_operand:HI 0 "register_operand" "")
3029         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3031 ;; When source and destination does not overlap, clear destination
3032 ;; first and then do the movb
3033 (define_split
3034   [(set (match_operand:HI 0 "register_operand" "")
3035         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3036    (clobber (reg:CC FLAGS_REG))]
3037   "reload_completed
3038    && ANY_QI_REG_P (operands[0])
3039    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3040    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3041   [(set (match_dup 0) (const_int 0))
3042    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3043   "operands[2] = gen_lowpart (QImode, operands[0]);")
3045 ;; Rest is handled by single and.
3046 (define_split
3047   [(set (match_operand:HI 0 "register_operand" "")
3048         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3049    (clobber (reg:CC FLAGS_REG))]
3050   "reload_completed
3051    && true_regnum (operands[0]) == true_regnum (operands[1])"
3052   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3053               (clobber (reg:CC FLAGS_REG))])]
3054   "")
3056 (define_expand "zero_extendqisi2"
3057   [(parallel
3058     [(set (match_operand:SI 0 "register_operand" "")
3059        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3060      (clobber (reg:CC FLAGS_REG))])]
3061   ""
3062   "")
3064 (define_insn "*zero_extendqisi2_and"
3065   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3066      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3067    (clobber (reg:CC FLAGS_REG))]
3068   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3069   "#"
3070   [(set_attr "type" "alu1")
3071    (set_attr "mode" "SI")])
3073 (define_insn "*zero_extendqisi2_movzbw_and"
3074   [(set (match_operand:SI 0 "register_operand" "=r,r")
3075      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3076    (clobber (reg:CC FLAGS_REG))]
3077   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3078   "#"
3079   [(set_attr "type" "imovx,alu1")
3080    (set_attr "mode" "SI")])
3082 (define_insn "*zero_extendqisi2_movzbw"
3083   [(set (match_operand:SI 0 "register_operand" "=r")
3084      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3085   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3086   "movz{bl|x}\t{%1, %0|%0, %1}"
3087   [(set_attr "type" "imovx")
3088    (set_attr "mode" "SI")])
3090 ;; For the movzbl case strip only the clobber
3091 (define_split
3092   [(set (match_operand:SI 0 "register_operand" "")
3093         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3094    (clobber (reg:CC FLAGS_REG))]
3095   "reload_completed 
3096    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3097    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3098   [(set (match_dup 0)
3099         (zero_extend:SI (match_dup 1)))])
3101 ;; When source and destination does not overlap, clear destination
3102 ;; first and then do the movb
3103 (define_split
3104   [(set (match_operand:SI 0 "register_operand" "")
3105         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3106    (clobber (reg:CC FLAGS_REG))]
3107   "reload_completed
3108    && ANY_QI_REG_P (operands[0])
3109    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3110    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3111    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3112   [(set (match_dup 0) (const_int 0))
3113    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3114   "operands[2] = gen_lowpart (QImode, operands[0]);")
3116 ;; Rest is handled by single and.
3117 (define_split
3118   [(set (match_operand:SI 0 "register_operand" "")
3119         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3120    (clobber (reg:CC FLAGS_REG))]
3121   "reload_completed
3122    && true_regnum (operands[0]) == true_regnum (operands[1])"
3123   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3124               (clobber (reg:CC FLAGS_REG))])]
3125   "")
3127 ;; %%% Kill me once multi-word ops are sane.
3128 (define_expand "zero_extendsidi2"
3129   [(set (match_operand:DI 0 "register_operand" "=r")
3130      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3131   ""
3132   "if (!TARGET_64BIT)
3133      {
3134        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3135        DONE;
3136      }
3137   ")
3139 (define_insn "zero_extendsidi2_32"
3140   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3141         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3142    (clobber (reg:CC FLAGS_REG))]
3143   "!TARGET_64BIT"
3144   "@
3145    #
3146    #
3147    #
3148    movd\t{%1, %0|%0, %1}
3149    movd\t{%1, %0|%0, %1}"
3150   [(set_attr "mode" "SI,SI,SI,DI,TI")
3151    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3153 (define_insn "zero_extendsidi2_rex64"
3154   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3155      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3156   "TARGET_64BIT"
3157   "@
3158    mov\t{%k1, %k0|%k0, %k1}
3159    #
3160    movd\t{%1, %0|%0, %1}
3161    movd\t{%1, %0|%0, %1}"
3162   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3163    (set_attr "mode" "SI,DI,SI,SI")])
3165 (define_split
3166   [(set (match_operand:DI 0 "memory_operand" "")
3167      (zero_extend:DI (match_dup 0)))]
3168   "TARGET_64BIT"
3169   [(set (match_dup 4) (const_int 0))]
3170   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3172 (define_split 
3173   [(set (match_operand:DI 0 "register_operand" "")
3174         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3175    (clobber (reg:CC FLAGS_REG))]
3176   "!TARGET_64BIT && reload_completed
3177    && true_regnum (operands[0]) == true_regnum (operands[1])"
3178   [(set (match_dup 4) (const_int 0))]
3179   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3181 (define_split 
3182   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3183         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3184    (clobber (reg:CC FLAGS_REG))]
3185   "!TARGET_64BIT && reload_completed
3186    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3187   [(set (match_dup 3) (match_dup 1))
3188    (set (match_dup 4) (const_int 0))]
3189   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3191 (define_insn "zero_extendhidi2"
3192   [(set (match_operand:DI 0 "register_operand" "=r,r")
3193      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3194   "TARGET_64BIT"
3195   "@
3196    movz{wl|x}\t{%1, %k0|%k0, %1}
3197    movz{wq|x}\t{%1, %0|%0, %1}"
3198   [(set_attr "type" "imovx")
3199    (set_attr "mode" "SI,DI")])
3201 (define_insn "zero_extendqidi2"
3202   [(set (match_operand:DI 0 "register_operand" "=r,r")
3203      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3204   "TARGET_64BIT"
3205   "@
3206    movz{bl|x}\t{%1, %k0|%k0, %1}
3207    movz{bq|x}\t{%1, %0|%0, %1}"
3208   [(set_attr "type" "imovx")
3209    (set_attr "mode" "SI,DI")])
3211 ;; Sign extension instructions
3213 (define_expand "extendsidi2"
3214   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3215                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3216               (clobber (reg:CC FLAGS_REG))
3217               (clobber (match_scratch:SI 2 ""))])]
3218   ""
3220   if (TARGET_64BIT)
3221     {
3222       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3223       DONE;
3224     }
3227 (define_insn "*extendsidi2_1"
3228   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3229         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3230    (clobber (reg:CC FLAGS_REG))
3231    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3232   "!TARGET_64BIT"
3233   "#")
3235 (define_insn "extendsidi2_rex64"
3236   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3237         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3238   "TARGET_64BIT"
3239   "@
3240    {cltq|cdqe}
3241    movs{lq|x}\t{%1,%0|%0, %1}"
3242   [(set_attr "type" "imovx")
3243    (set_attr "mode" "DI")
3244    (set_attr "prefix_0f" "0")
3245    (set_attr "modrm" "0,1")])
3247 (define_insn "extendhidi2"
3248   [(set (match_operand:DI 0 "register_operand" "=r")
3249         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3250   "TARGET_64BIT"
3251   "movs{wq|x}\t{%1,%0|%0, %1}"
3252   [(set_attr "type" "imovx")
3253    (set_attr "mode" "DI")])
3255 (define_insn "extendqidi2"
3256   [(set (match_operand:DI 0 "register_operand" "=r")
3257         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3258   "TARGET_64BIT"
3259   "movs{bq|x}\t{%1,%0|%0, %1}"
3260    [(set_attr "type" "imovx")
3261     (set_attr "mode" "DI")])
3263 ;; Extend to memory case when source register does die.
3264 (define_split 
3265   [(set (match_operand:DI 0 "memory_operand" "")
3266         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3267    (clobber (reg:CC FLAGS_REG))
3268    (clobber (match_operand:SI 2 "register_operand" ""))]
3269   "(reload_completed
3270     && dead_or_set_p (insn, operands[1])
3271     && !reg_mentioned_p (operands[1], operands[0]))"
3272   [(set (match_dup 3) (match_dup 1))
3273    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3274               (clobber (reg:CC FLAGS_REG))])
3275    (set (match_dup 4) (match_dup 1))]
3276   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3278 ;; Extend to memory case when source register does not die.
3279 (define_split 
3280   [(set (match_operand:DI 0 "memory_operand" "")
3281         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3282    (clobber (reg:CC FLAGS_REG))
3283    (clobber (match_operand:SI 2 "register_operand" ""))]
3284   "reload_completed"
3285   [(const_int 0)]
3287   split_di (&operands[0], 1, &operands[3], &operands[4]);
3289   emit_move_insn (operands[3], operands[1]);
3291   /* Generate a cltd if possible and doing so it profitable.  */
3292   if (true_regnum (operands[1]) == 0
3293       && true_regnum (operands[2]) == 1
3294       && (optimize_size || TARGET_USE_CLTD))
3295     {
3296       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3297     }
3298   else
3299     {
3300       emit_move_insn (operands[2], operands[1]);
3301       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3302     }
3303   emit_move_insn (operands[4], operands[2]);
3304   DONE;
3307 ;; Extend to register case.  Optimize case where source and destination
3308 ;; registers match and cases where we can use cltd.
3309 (define_split 
3310   [(set (match_operand:DI 0 "register_operand" "")
3311         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3312    (clobber (reg:CC FLAGS_REG))
3313    (clobber (match_scratch:SI 2 ""))]
3314   "reload_completed"
3315   [(const_int 0)]
3317   split_di (&operands[0], 1, &operands[3], &operands[4]);
3319   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3320     emit_move_insn (operands[3], operands[1]);
3322   /* Generate a cltd if possible and doing so it profitable.  */
3323   if (true_regnum (operands[3]) == 0
3324       && (optimize_size || TARGET_USE_CLTD))
3325     {
3326       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3327       DONE;
3328     }
3330   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3331     emit_move_insn (operands[4], operands[1]);
3333   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3334   DONE;
3337 (define_insn "extendhisi2"
3338   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3339         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3340   ""
3342   switch (get_attr_prefix_0f (insn))
3343     {
3344     case 0:
3345       return "{cwtl|cwde}";
3346     default:
3347       return "movs{wl|x}\t{%1,%0|%0, %1}";
3348     }
3350   [(set_attr "type" "imovx")
3351    (set_attr "mode" "SI")
3352    (set (attr "prefix_0f")
3353      ;; movsx is short decodable while cwtl is vector decoded.
3354      (if_then_else (and (eq_attr "cpu" "!k6")
3355                         (eq_attr "alternative" "0"))
3356         (const_string "0")
3357         (const_string "1")))
3358    (set (attr "modrm")
3359      (if_then_else (eq_attr "prefix_0f" "0")
3360         (const_string "0")
3361         (const_string "1")))])
3363 (define_insn "*extendhisi2_zext"
3364   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3365         (zero_extend:DI
3366           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3367   "TARGET_64BIT"
3369   switch (get_attr_prefix_0f (insn))
3370     {
3371     case 0:
3372       return "{cwtl|cwde}";
3373     default:
3374       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3375     }
3377   [(set_attr "type" "imovx")
3378    (set_attr "mode" "SI")
3379    (set (attr "prefix_0f")
3380      ;; movsx is short decodable while cwtl is vector decoded.
3381      (if_then_else (and (eq_attr "cpu" "!k6")
3382                         (eq_attr "alternative" "0"))
3383         (const_string "0")
3384         (const_string "1")))
3385    (set (attr "modrm")
3386      (if_then_else (eq_attr "prefix_0f" "0")
3387         (const_string "0")
3388         (const_string "1")))])
3390 (define_insn "extendqihi2"
3391   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3392         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3393   ""
3395   switch (get_attr_prefix_0f (insn))
3396     {
3397     case 0:
3398       return "{cbtw|cbw}";
3399     default:
3400       return "movs{bw|x}\t{%1,%0|%0, %1}";
3401     }
3403   [(set_attr "type" "imovx")
3404    (set_attr "mode" "HI")
3405    (set (attr "prefix_0f")
3406      ;; movsx is short decodable while cwtl is vector decoded.
3407      (if_then_else (and (eq_attr "cpu" "!k6")
3408                         (eq_attr "alternative" "0"))
3409         (const_string "0")
3410         (const_string "1")))
3411    (set (attr "modrm")
3412      (if_then_else (eq_attr "prefix_0f" "0")
3413         (const_string "0")
3414         (const_string "1")))])
3416 (define_insn "extendqisi2"
3417   [(set (match_operand:SI 0 "register_operand" "=r")
3418         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3419   ""
3420   "movs{bl|x}\t{%1,%0|%0, %1}"
3421    [(set_attr "type" "imovx")
3422     (set_attr "mode" "SI")])
3424 (define_insn "*extendqisi2_zext"
3425   [(set (match_operand:DI 0 "register_operand" "=r")
3426         (zero_extend:DI
3427           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3428   "TARGET_64BIT"
3429   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3430    [(set_attr "type" "imovx")
3431     (set_attr "mode" "SI")])
3433 ;; Conversions between float and double.
3435 ;; These are all no-ops in the model used for the 80387.  So just
3436 ;; emit moves.
3438 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3439 (define_insn "*dummy_extendsfdf2"
3440   [(set (match_operand:DF 0 "push_operand" "=<")
3441         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3442   "0"
3443   "#")
3445 (define_split
3446   [(set (match_operand:DF 0 "push_operand" "")
3447         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3448   "!TARGET_64BIT"
3449   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3450    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3452 (define_split
3453   [(set (match_operand:DF 0 "push_operand" "")
3454         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3455   "TARGET_64BIT"
3456   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3457    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3459 (define_insn "*dummy_extendsfxf2"
3460   [(set (match_operand:XF 0 "push_operand" "=<")
3461         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3462   "0"
3463   "#")
3465 (define_split
3466   [(set (match_operand:XF 0 "push_operand" "")
3467         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3468   ""
3469   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3470    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3471   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3473 (define_split
3474   [(set (match_operand:XF 0 "push_operand" "")
3475         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3476   "TARGET_64BIT"
3477   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3478    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3479   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3481 (define_split
3482   [(set (match_operand:XF 0 "push_operand" "")
3483         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3484   ""
3485   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3486    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3487   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3489 (define_split
3490   [(set (match_operand:XF 0 "push_operand" "")
3491         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3492   "TARGET_64BIT"
3493   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3494    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3495   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3497 (define_expand "extendsfdf2"
3498   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3499         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3500   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3502   /* ??? Needed for compress_float_constant since all fp constants
3503      are LEGITIMATE_CONSTANT_P.  */
3504   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3505     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3506   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3507     operands[1] = force_reg (SFmode, operands[1]);
3510 (define_insn "*extendsfdf2_mixed"
3511   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3512         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3513   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3514    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3516   switch (which_alternative)
3517     {
3518     case 0:
3519       return output_387_reg_move (insn, operands);
3521     case 1:
3522       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3523         return "fstp%z0\t%y0";
3524       else
3525         return "fst%z0\t%y0";
3527     case 2:
3528       return "cvtss2sd\t{%1, %0|%0, %1}";
3530     default:
3531       gcc_unreachable ();
3532     }
3534   [(set_attr "type" "fmov,fmov,ssecvt")
3535    (set_attr "mode" "SF,XF,DF")])
3537 (define_insn "*extendsfdf2_sse"
3538   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3539         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3540   "TARGET_SSE2 && TARGET_SSE_MATH
3541    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3542   "cvtss2sd\t{%1, %0|%0, %1}"
3543   [(set_attr "type" "ssecvt")
3544    (set_attr "mode" "DF")])
3546 (define_insn "*extendsfdf2_i387"
3547   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3548         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3549   "TARGET_80387
3550    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3552   switch (which_alternative)
3553     {
3554     case 0:
3555       return output_387_reg_move (insn, operands);
3557     case 1:
3558       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3559         return "fstp%z0\t%y0";
3560       else
3561         return "fst%z0\t%y0";
3563     default:
3564       gcc_unreachable ();
3565     }
3567   [(set_attr "type" "fmov")
3568    (set_attr "mode" "SF,XF")])
3570 (define_expand "extendsfxf2"
3571   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3572         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3573   "TARGET_80387"
3575   /* ??? Needed for compress_float_constant since all fp constants
3576      are LEGITIMATE_CONSTANT_P.  */
3577   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3578     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3579   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3580     operands[1] = force_reg (SFmode, operands[1]);
3583 (define_insn "*extendsfxf2_i387"
3584   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3585         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3586   "TARGET_80387
3587    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3589   switch (which_alternative)
3590     {
3591     case 0:
3592       return output_387_reg_move (insn, operands);
3594     case 1:
3595       /* There is no non-popping store to memory for XFmode.  So if
3596          we need one, follow the store with a load.  */
3597       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3598         return "fstp%z0\t%y0";
3599       else
3600         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3602     default:
3603       gcc_unreachable ();
3604     }
3606   [(set_attr "type" "fmov")
3607    (set_attr "mode" "SF,XF")])
3609 (define_expand "extenddfxf2"
3610   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3611         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3612   "TARGET_80387"
3614   /* ??? Needed for compress_float_constant since all fp constants
3615      are LEGITIMATE_CONSTANT_P.  */
3616   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3617     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3618   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3619     operands[1] = force_reg (DFmode, operands[1]);
3622 (define_insn "*extenddfxf2_i387"
3623   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3624         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3625   "TARGET_80387
3626    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3628   switch (which_alternative)
3629     {
3630     case 0:
3631       return output_387_reg_move (insn, operands);
3633     case 1:
3634       /* There is no non-popping store to memory for XFmode.  So if
3635          we need one, follow the store with a load.  */
3636       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3638       else
3639         return "fstp%z0\t%y0";
3641     default:
3642       gcc_unreachable ();
3643     }
3645   [(set_attr "type" "fmov")
3646    (set_attr "mode" "DF,XF")])
3648 ;; %%% This seems bad bad news.
3649 ;; This cannot output into an f-reg because there is no way to be sure
3650 ;; of truncating in that case.  Otherwise this is just like a simple move
3651 ;; insn.  So we pretend we can output to a reg in order to get better
3652 ;; register preferencing, but we really use a stack slot.
3654 ;; Conversion from DFmode to SFmode.
3656 (define_expand "truncdfsf2"
3657   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3658         (float_truncate:SF
3659           (match_operand:DF 1 "nonimmediate_operand" "")))]
3660   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3662   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3663     operands[1] = force_reg (DFmode, operands[1]);
3665   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3666     ;
3667   else if (flag_unsafe_math_optimizations)
3668     ;
3669   else
3670     {
3671       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3672       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3673       DONE;
3674     }
3677 (define_expand "truncdfsf2_with_temp"
3678   [(parallel [(set (match_operand:SF 0 "" "")
3679                    (float_truncate:SF (match_operand:DF 1 "" "")))
3680               (clobber (match_operand:SF 2 "" ""))])]
3681   "")
3683 (define_insn "*truncdfsf_fast_mixed"
3684   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3685         (float_truncate:SF
3686           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3687   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3689   switch (which_alternative)
3690     {
3691     case 0:
3692       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3693         return "fstp%z0\t%y0";
3694       else
3695         return "fst%z0\t%y0";
3696     case 1:
3697       return output_387_reg_move (insn, operands);
3698     case 2:
3699       return "cvtsd2ss\t{%1, %0|%0, %1}";
3700     default:
3701       gcc_unreachable ();
3702     }
3704   [(set_attr "type" "fmov,fmov,ssecvt")
3705    (set_attr "mode" "SF")])
3707 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3708 ;; because nothing we do here is unsafe.
3709 (define_insn "*truncdfsf_fast_sse"
3710   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3711         (float_truncate:SF
3712           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3713   "TARGET_SSE2 && TARGET_SSE_MATH"
3714   "cvtsd2ss\t{%1, %0|%0, %1}"
3715   [(set_attr "type" "ssecvt")
3716    (set_attr "mode" "SF")])
3718 (define_insn "*truncdfsf_fast_i387"
3719   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3720         (float_truncate:SF
3721           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3722   "TARGET_80387 && flag_unsafe_math_optimizations"
3723   "* return output_387_reg_move (insn, operands);"
3724   [(set_attr "type" "fmov")
3725    (set_attr "mode" "SF")])
3727 (define_insn "*truncdfsf_mixed"
3728   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3729         (float_truncate:SF
3730           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3731    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3732   "TARGET_MIX_SSE_I387"
3734   switch (which_alternative)
3735     {
3736     case 0:
3737       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3738         return "fstp%z0\t%y0";
3739       else
3740         return "fst%z0\t%y0";
3741     case 1:
3742       return "#";
3743     case 2:
3744       return "cvtsd2ss\t{%1, %0|%0, %1}";
3745     default:
3746       gcc_unreachable ();
3747     }
3749   [(set_attr "type" "fmov,multi,ssecvt")
3750    (set_attr "unit" "*,i387,*")
3751    (set_attr "mode" "SF")])
3753 (define_insn "*truncdfsf_i387"
3754   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3755         (float_truncate:SF
3756           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3757    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3758   "TARGET_80387"
3760   switch (which_alternative)
3761     {
3762     case 0:
3763       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3764         return "fstp%z0\t%y0";
3765       else
3766         return "fst%z0\t%y0";
3767     case 1:
3768       return "#";
3769     default:
3770       gcc_unreachable ();
3771     }
3773   [(set_attr "type" "fmov,multi")
3774    (set_attr "unit" "*,i387")
3775    (set_attr "mode" "SF")])
3777 (define_insn "*truncdfsf2_i387_1"
3778   [(set (match_operand:SF 0 "memory_operand" "=m")
3779         (float_truncate:SF
3780           (match_operand:DF 1 "register_operand" "f")))]
3781   "TARGET_80387
3782    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3783    && !TARGET_MIX_SSE_I387"
3785   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786     return "fstp%z0\t%y0";
3787   else
3788     return "fst%z0\t%y0";
3790   [(set_attr "type" "fmov")
3791    (set_attr "mode" "SF")])
3793 (define_split
3794   [(set (match_operand:SF 0 "register_operand" "")
3795         (float_truncate:SF
3796          (match_operand:DF 1 "fp_register_operand" "")))
3797    (clobber (match_operand 2 "" ""))]
3798   "reload_completed"
3799   [(set (match_dup 2) (match_dup 1))
3800    (set (match_dup 0) (match_dup 2))]
3802   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3805 ;; Conversion from XFmode to SFmode.
3807 (define_expand "truncxfsf2"
3808   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3809                    (float_truncate:SF
3810                     (match_operand:XF 1 "register_operand" "")))
3811               (clobber (match_dup 2))])]
3812   "TARGET_80387"
3814   if (flag_unsafe_math_optimizations)
3815     {
3816       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3817       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3818       if (reg != operands[0])
3819         emit_move_insn (operands[0], reg);
3820       DONE;
3821     }
3822   else
3823     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3826 (define_insn "*truncxfsf2_mixed"
3827   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3828         (float_truncate:SF
3829          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3830    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3831   "TARGET_MIX_SSE_I387"
3833   gcc_assert (!which_alternative);
3834   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3835     return "fstp%z0\t%y0";
3836   else
3837     return "fst%z0\t%y0";
3839   [(set_attr "type" "fmov,multi,multi,multi")
3840    (set_attr "unit" "*,i387,i387,i387")
3841    (set_attr "mode" "SF")])
3843 (define_insn "truncxfsf2_i387_noop"
3844   [(set (match_operand:SF 0 "register_operand" "=f")
3845         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3846   "TARGET_80387 && flag_unsafe_math_optimizations"
3848   return output_387_reg_move (insn, operands);
3850   [(set_attr "type" "fmov")
3851    (set_attr "mode" "SF")])
3853 (define_insn "*truncxfsf2_i387"
3854   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3855         (float_truncate:SF
3856          (match_operand:XF 1 "register_operand" "f,f,f")))
3857    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3858   "TARGET_80387"
3860   gcc_assert (!which_alternative);
3861   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3862     return "fstp%z0\t%y0";
3863    else
3864      return "fst%z0\t%y0";
3866   [(set_attr "type" "fmov,multi,multi")
3867    (set_attr "unit" "*,i387,i387")
3868    (set_attr "mode" "SF")])
3870 (define_insn "*truncxfsf2_i387_1"
3871   [(set (match_operand:SF 0 "memory_operand" "=m")
3872         (float_truncate:SF
3873          (match_operand:XF 1 "register_operand" "f")))]
3874   "TARGET_80387"
3876   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877     return "fstp%z0\t%y0";
3878   else
3879     return "fst%z0\t%y0";
3881   [(set_attr "type" "fmov")
3882    (set_attr "mode" "SF")])
3884 (define_split
3885   [(set (match_operand:SF 0 "register_operand" "")
3886         (float_truncate:SF
3887          (match_operand:XF 1 "register_operand" "")))
3888    (clobber (match_operand:SF 2 "memory_operand" ""))]
3889   "TARGET_80387 && reload_completed"
3890   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3891    (set (match_dup 0) (match_dup 2))]
3892   "")
3894 (define_split
3895   [(set (match_operand:SF 0 "memory_operand" "")
3896         (float_truncate:SF
3897          (match_operand:XF 1 "register_operand" "")))
3898    (clobber (match_operand:SF 2 "memory_operand" ""))]
3899   "TARGET_80387"
3900   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3901   "")
3903 ;; Conversion from XFmode to DFmode.
3905 (define_expand "truncxfdf2"
3906   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3907                    (float_truncate:DF
3908                     (match_operand:XF 1 "register_operand" "")))
3909               (clobber (match_dup 2))])]
3910   "TARGET_80387"
3912   if (flag_unsafe_math_optimizations)
3913     {
3914       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3915       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3916       if (reg != operands[0])
3917         emit_move_insn (operands[0], reg);
3918       DONE;
3919     }
3920   else
3921     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3924 (define_insn "*truncxfdf2_mixed"
3925   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3926         (float_truncate:DF
3927          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3928    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3929   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3931   gcc_assert (!which_alternative);
3932   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3933     return "fstp%z0\t%y0";
3934   else
3935     return "fst%z0\t%y0";
3937   [(set_attr "type" "fmov,multi,multi,multi")
3938    (set_attr "unit" "*,i387,i387,i387")
3939    (set_attr "mode" "DF")])
3941 (define_insn "truncxfdf2_i387_noop"
3942   [(set (match_operand:DF 0 "register_operand" "=f")
3943         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3944   "TARGET_80387 && flag_unsafe_math_optimizations"
3946   return output_387_reg_move (insn, operands);
3948   [(set_attr "type" "fmov")
3949    (set_attr "mode" "DF")])
3951 (define_insn "*truncxfdf2_i387"
3952   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3953         (float_truncate:DF
3954          (match_operand:XF 1 "register_operand" "f,f,f")))
3955    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3956   "TARGET_80387"
3958   gcc_assert (!which_alternative);
3959   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3960     return "fstp%z0\t%y0";
3961   else
3962     return "fst%z0\t%y0";
3964   [(set_attr "type" "fmov,multi,multi")
3965    (set_attr "unit" "*,i387,i387")
3966    (set_attr "mode" "DF")])
3968 (define_insn "*truncxfdf2_i387_1"
3969   [(set (match_operand:DF 0 "memory_operand" "=m")
3970         (float_truncate:DF
3971           (match_operand:XF 1 "register_operand" "f")))]
3972   "TARGET_80387"
3974   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3975     return "fstp%z0\t%y0";
3976   else
3977     return "fst%z0\t%y0";
3979   [(set_attr "type" "fmov")
3980    (set_attr "mode" "DF")])
3982 (define_split
3983   [(set (match_operand:DF 0 "register_operand" "")
3984         (float_truncate:DF
3985          (match_operand:XF 1 "register_operand" "")))
3986    (clobber (match_operand:DF 2 "memory_operand" ""))]
3987   "TARGET_80387 && reload_completed"
3988   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
3989    (set (match_dup 0) (match_dup 2))]
3990   "")
3992 (define_split
3993   [(set (match_operand:DF 0 "memory_operand" "")
3994         (float_truncate:DF
3995          (match_operand:XF 1 "register_operand" "")))
3996    (clobber (match_operand:DF 2 "memory_operand" ""))]
3997   "TARGET_80387"
3998   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
3999   "")
4001 ;; Signed conversion to DImode.
4003 (define_expand "fix_truncxfdi2"
4004   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4005                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4006               (clobber (reg:CC FLAGS_REG))])]
4007   "TARGET_80387"
4009   if (TARGET_FISTTP)
4010    {
4011      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4012      DONE;
4013    }
4016 (define_expand "fix_trunc<mode>di2"
4017   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4018                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4019               (clobber (reg:CC FLAGS_REG))])]
4020   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4022   if (TARGET_FISTTP
4023       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4024    {
4025      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4026      DONE;
4027    }
4028   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4029    {
4030      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4031      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4032      if (out != operands[0])
4033         emit_move_insn (operands[0], out);
4034      DONE;
4035    }
4038 ;; Signed conversion to SImode.
4040 (define_expand "fix_truncxfsi2"
4041   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4042                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4043               (clobber (reg:CC FLAGS_REG))])]
4044   "TARGET_80387"
4046   if (TARGET_FISTTP)
4047    {
4048      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4049      DONE;
4050    }
4053 (define_expand "fix_trunc<mode>si2"
4054   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4055                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4056               (clobber (reg:CC FLAGS_REG))])]
4057   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4059   if (TARGET_FISTTP
4060       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4061    {
4062      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4063      DONE;
4064    }
4065   if (SSE_FLOAT_MODE_P (<MODE>mode))
4066    {
4067      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4068      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4069      if (out != operands[0])
4070         emit_move_insn (operands[0], out);
4071      DONE;
4072    }
4075 ;; Signed conversion to HImode.
4077 (define_expand "fix_trunc<mode>hi2"
4078   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4079                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4080               (clobber (reg:CC FLAGS_REG))])]
4081   "TARGET_80387
4082    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4084   if (TARGET_FISTTP)
4085    {
4086      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4087      DONE;
4088    }
4091 ;; When SSE is available, it is always faster to use it!
4092 (define_insn "fix_truncsfdi_sse"
4093   [(set (match_operand:DI 0 "register_operand" "=r,r")
4094         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4095   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4096   "cvttss2si{q}\t{%1, %0|%0, %1}"
4097   [(set_attr "type" "sseicvt")
4098    (set_attr "mode" "SF")
4099    (set_attr "athlon_decode" "double,vector")])
4101 (define_insn "fix_truncdfdi_sse"
4102   [(set (match_operand:DI 0 "register_operand" "=r,r")
4103         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4104   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4105   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4106   [(set_attr "type" "sseicvt")
4107    (set_attr "mode" "DF")
4108    (set_attr "athlon_decode" "double,vector")])
4110 (define_insn "fix_truncsfsi_sse"
4111   [(set (match_operand:SI 0 "register_operand" "=r,r")
4112         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4113   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4114   "cvttss2si\t{%1, %0|%0, %1}"
4115   [(set_attr "type" "sseicvt")
4116    (set_attr "mode" "DF")
4117    (set_attr "athlon_decode" "double,vector")])
4119 (define_insn "fix_truncdfsi_sse"
4120   [(set (match_operand:SI 0 "register_operand" "=r,r")
4121         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4122   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4123   "cvttsd2si\t{%1, %0|%0, %1}"
4124   [(set_attr "type" "sseicvt")
4125    (set_attr "mode" "DF")
4126    (set_attr "athlon_decode" "double,vector")])
4128 ;; Avoid vector decoded forms of the instruction.
4129 (define_peephole2
4130   [(match_scratch:DF 2 "Y")
4131    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4132         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4133   "TARGET_K8 && !optimize_size"
4134   [(set (match_dup 2) (match_dup 1))
4135    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4136   "")
4138 (define_peephole2
4139   [(match_scratch:SF 2 "x")
4140    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4141         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4142   "TARGET_K8 && !optimize_size"
4143   [(set (match_dup 2) (match_dup 1))
4144    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4145   "")
4147 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4148   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4149         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4150   "TARGET_80387 && TARGET_FISTTP
4151    && FLOAT_MODE_P (GET_MODE (operands[1]))
4152    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4153          && (TARGET_64BIT || <MODE>mode != DImode))
4154         && TARGET_SSE_MATH)
4155    && !(reload_completed || reload_in_progress)"
4156   "#"
4157   "&& 1"
4158   [(const_int 0)]
4160   if (memory_operand (operands[0], VOIDmode))
4161     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4162   else
4163     {
4164       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4165       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4166                                                             operands[1],
4167                                                             operands[2]));
4168     }
4169   DONE;
4171   [(set_attr "type" "fisttp")
4172    (set_attr "mode" "<MODE>")])
4174 (define_insn "fix_trunc<mode>_i387_fisttp"
4175   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4176         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4177    (clobber (match_scratch:XF 2 "=&1f"))]
4178   "TARGET_80387 && TARGET_FISTTP
4179    && FLOAT_MODE_P (GET_MODE (operands[1]))
4180    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4181          && (TARGET_64BIT || <MODE>mode != DImode))
4182         && TARGET_SSE_MATH)"
4183   "* return output_fix_trunc (insn, operands, 1);"
4184   [(set_attr "type" "fisttp")
4185    (set_attr "mode" "<MODE>")])
4187 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4188   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4189         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4190    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4191    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4192   "TARGET_80387 && TARGET_FISTTP
4193    && FLOAT_MODE_P (GET_MODE (operands[1]))
4194    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4195         && (TARGET_64BIT || <MODE>mode != DImode))
4196         && TARGET_SSE_MATH)"
4197   "#"
4198   [(set_attr "type" "fisttp")
4199    (set_attr "mode" "<MODE>")])
4201 (define_split
4202   [(set (match_operand:X87MODEI 0 "register_operand" "")
4203         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4204    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4205    (clobber (match_scratch 3 ""))]
4206   "reload_completed"
4207   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4208               (clobber (match_dup 3))])
4209    (set (match_dup 0) (match_dup 2))]
4210   "")
4212 (define_split
4213   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4214         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4215    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4216    (clobber (match_scratch 3 ""))]
4217   "reload_completed"
4218   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4219               (clobber (match_dup 3))])]
4220   "")
4222 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4223 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4224 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4225 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4226 ;; function in i386.c.
4227 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4228   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4229         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4230    (clobber (reg:CC FLAGS_REG))]
4231   "TARGET_80387 && !TARGET_FISTTP
4232    && FLOAT_MODE_P (GET_MODE (operands[1]))
4233    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4234          && (TARGET_64BIT || <MODE>mode != DImode))
4235    && !(reload_completed || reload_in_progress)"
4236   "#"
4237   "&& 1"
4238   [(const_int 0)]
4240   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4242   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4243   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4244   if (memory_operand (operands[0], VOIDmode))
4245     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4246                                          operands[2], operands[3]));
4247   else
4248     {
4249       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4250       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4251                                                      operands[2], operands[3],
4252                                                      operands[4]));
4253     }
4254   DONE;
4256   [(set_attr "type" "fistp")
4257    (set_attr "i387_cw" "trunc")
4258    (set_attr "mode" "<MODE>")])
4260 (define_insn "fix_truncdi_i387"
4261   [(set (match_operand:DI 0 "memory_operand" "=m")
4262         (fix:DI (match_operand 1 "register_operand" "f")))
4263    (use (match_operand:HI 2 "memory_operand" "m"))
4264    (use (match_operand:HI 3 "memory_operand" "m"))
4265    (clobber (match_scratch:XF 4 "=&1f"))]
4266   "TARGET_80387 && !TARGET_FISTTP
4267    && FLOAT_MODE_P (GET_MODE (operands[1]))
4268    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4269   "* return output_fix_trunc (insn, operands, 0);"
4270   [(set_attr "type" "fistp")
4271    (set_attr "i387_cw" "trunc")
4272    (set_attr "mode" "DI")])
4274 (define_insn "fix_truncdi_i387_with_temp"
4275   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4276         (fix:DI (match_operand 1 "register_operand" "f,f")))
4277    (use (match_operand:HI 2 "memory_operand" "m,m"))
4278    (use (match_operand:HI 3 "memory_operand" "m,m"))
4279    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4280    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4281   "TARGET_80387 && !TARGET_FISTTP
4282    && FLOAT_MODE_P (GET_MODE (operands[1]))
4283    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4284   "#"
4285   [(set_attr "type" "fistp")
4286    (set_attr "i387_cw" "trunc")
4287    (set_attr "mode" "DI")])
4289 (define_split 
4290   [(set (match_operand:DI 0 "register_operand" "")
4291         (fix:DI (match_operand 1 "register_operand" "")))
4292    (use (match_operand:HI 2 "memory_operand" ""))
4293    (use (match_operand:HI 3 "memory_operand" ""))
4294    (clobber (match_operand:DI 4 "memory_operand" ""))
4295    (clobber (match_scratch 5 ""))]
4296   "reload_completed"
4297   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4298               (use (match_dup 2))
4299               (use (match_dup 3))
4300               (clobber (match_dup 5))])
4301    (set (match_dup 0) (match_dup 4))]
4302   "")
4304 (define_split 
4305   [(set (match_operand:DI 0 "memory_operand" "")
4306         (fix:DI (match_operand 1 "register_operand" "")))
4307    (use (match_operand:HI 2 "memory_operand" ""))
4308    (use (match_operand:HI 3 "memory_operand" ""))
4309    (clobber (match_operand:DI 4 "memory_operand" ""))
4310    (clobber (match_scratch 5 ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4313               (use (match_dup 2))
4314               (use (match_dup 3))
4315               (clobber (match_dup 5))])]
4316   "")
4318 (define_insn "fix_trunc<mode>_i387"
4319   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4320         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4321    (use (match_operand:HI 2 "memory_operand" "m"))
4322    (use (match_operand:HI 3 "memory_operand" "m"))]
4323   "TARGET_80387 && !TARGET_FISTTP
4324    && FLOAT_MODE_P (GET_MODE (operands[1]))
4325    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4326   "* return output_fix_trunc (insn, operands, 0);"
4327   [(set_attr "type" "fistp")
4328    (set_attr "i387_cw" "trunc")
4329    (set_attr "mode" "<MODE>")])
4331 (define_insn "fix_trunc<mode>_i387_with_temp"
4332   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4333         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4334    (use (match_operand:HI 2 "memory_operand" "m,m"))
4335    (use (match_operand:HI 3 "memory_operand" "m,m"))
4336    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4337   "TARGET_80387 && !TARGET_FISTTP
4338    && FLOAT_MODE_P (GET_MODE (operands[1]))
4339    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4340   "#"
4341   [(set_attr "type" "fistp")
4342    (set_attr "i387_cw" "trunc")
4343    (set_attr "mode" "<MODE>")])
4345 (define_split 
4346   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4347         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4348    (use (match_operand:HI 2 "memory_operand" ""))
4349    (use (match_operand:HI 3 "memory_operand" ""))
4350    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4351   "reload_completed"
4352   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4353               (use (match_dup 2))
4354               (use (match_dup 3))])
4355    (set (match_dup 0) (match_dup 4))]
4356   "")
4358 (define_split 
4359   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4360         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4361    (use (match_operand:HI 2 "memory_operand" ""))
4362    (use (match_operand:HI 3 "memory_operand" ""))
4363    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4364   "reload_completed"
4365   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4366               (use (match_dup 2))
4367               (use (match_dup 3))])]
4368   "")
4370 (define_insn "x86_fnstcw_1"
4371   [(set (match_operand:HI 0 "memory_operand" "=m")
4372         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4373   "TARGET_80387"
4374   "fnstcw\t%0"
4375   [(set_attr "length" "2")
4376    (set_attr "mode" "HI")
4377    (set_attr "unit" "i387")])
4379 (define_insn "x86_fldcw_1"
4380   [(set (reg:HI FPSR_REG)
4381         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4382   "TARGET_80387"
4383   "fldcw\t%0"
4384   [(set_attr "length" "2")
4385    (set_attr "mode" "HI")
4386    (set_attr "unit" "i387")
4387    (set_attr "athlon_decode" "vector")])
4389 ;; Conversion between fixed point and floating point.
4391 ;; Even though we only accept memory inputs, the backend _really_
4392 ;; wants to be able to do this between registers.
4394 (define_expand "floathisf2"
4395   [(set (match_operand:SF 0 "register_operand" "")
4396         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4397   "TARGET_80387 || TARGET_SSE_MATH"
4399   if (TARGET_SSE_MATH)
4400     {
4401       emit_insn (gen_floatsisf2 (operands[0],
4402                                  convert_to_mode (SImode, operands[1], 0)));
4403       DONE;
4404     }
4407 (define_insn "*floathisf2_i387"
4408   [(set (match_operand:SF 0 "register_operand" "=f,f")
4409         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4410   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4411   "@
4412    fild%z1\t%1
4413    #"
4414   [(set_attr "type" "fmov,multi")
4415    (set_attr "mode" "SF")
4416    (set_attr "unit" "*,i387")
4417    (set_attr "fp_int_src" "true")])
4419 (define_expand "floatsisf2"
4420   [(set (match_operand:SF 0 "register_operand" "")
4421         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4422   "TARGET_80387 || TARGET_SSE_MATH"
4423   "")
4425 (define_insn "*floatsisf2_mixed"
4426   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4427         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4428   "TARGET_MIX_SSE_I387"
4429   "@
4430    fild%z1\t%1
4431    #
4432    cvtsi2ss\t{%1, %0|%0, %1}
4433    cvtsi2ss\t{%1, %0|%0, %1}"
4434   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4435    (set_attr "mode" "SF")
4436    (set_attr "unit" "*,i387,*,*")
4437    (set_attr "athlon_decode" "*,*,vector,double")
4438    (set_attr "fp_int_src" "true")])
4440 (define_insn "*floatsisf2_sse"
4441   [(set (match_operand:SF 0 "register_operand" "=x,x")
4442         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4443   "TARGET_SSE_MATH"
4444   "cvtsi2ss\t{%1, %0|%0, %1}"
4445   [(set_attr "type" "sseicvt")
4446    (set_attr "mode" "SF")
4447    (set_attr "athlon_decode" "vector,double")
4448    (set_attr "fp_int_src" "true")])
4450 (define_insn "*floatsisf2_i387"
4451   [(set (match_operand:SF 0 "register_operand" "=f,f")
4452         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4453   "TARGET_80387"
4454   "@
4455    fild%z1\t%1
4456    #"
4457   [(set_attr "type" "fmov,multi")
4458    (set_attr "mode" "SF")
4459    (set_attr "unit" "*,i387")
4460    (set_attr "fp_int_src" "true")])
4462 (define_expand "floatdisf2"
4463   [(set (match_operand:SF 0 "register_operand" "")
4464         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4465   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4466   "")
4468 (define_insn "*floatdisf2_mixed"
4469   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4470         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4471   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4472   "@
4473    fild%z1\t%1
4474    #
4475    cvtsi2ss{q}\t{%1, %0|%0, %1}
4476    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4477   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4478    (set_attr "mode" "SF")
4479    (set_attr "unit" "*,i387,*,*")
4480    (set_attr "athlon_decode" "*,*,vector,double")
4481    (set_attr "fp_int_src" "true")])
4483 (define_insn "*floatdisf2_sse"
4484   [(set (match_operand:SF 0 "register_operand" "=x,x")
4485         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4486   "TARGET_64BIT && TARGET_SSE_MATH"
4487   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4488   [(set_attr "type" "sseicvt")
4489    (set_attr "mode" "SF")
4490    (set_attr "athlon_decode" "vector,double")
4491    (set_attr "fp_int_src" "true")])
4493 (define_insn "*floatdisf2_i387"
4494   [(set (match_operand:SF 0 "register_operand" "=f,f")
4495         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4496   "TARGET_80387"
4497   "@
4498    fild%z1\t%1
4499    #"
4500   [(set_attr "type" "fmov,multi")
4501    (set_attr "mode" "SF")
4502    (set_attr "unit" "*,i387")
4503    (set_attr "fp_int_src" "true")])
4505 (define_expand "floathidf2"
4506   [(set (match_operand:DF 0 "register_operand" "")
4507         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4508   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4510   if (TARGET_SSE2 && TARGET_SSE_MATH)
4511     {
4512       emit_insn (gen_floatsidf2 (operands[0],
4513                                  convert_to_mode (SImode, operands[1], 0)));
4514       DONE;
4515     }
4518 (define_insn "*floathidf2_i387"
4519   [(set (match_operand:DF 0 "register_operand" "=f,f")
4520         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4521   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4522   "@
4523    fild%z1\t%1
4524    #"
4525   [(set_attr "type" "fmov,multi")
4526    (set_attr "mode" "DF")
4527    (set_attr "unit" "*,i387")
4528    (set_attr "fp_int_src" "true")])
4530 (define_expand "floatsidf2"
4531   [(set (match_operand:DF 0 "register_operand" "")
4532         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4533   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4534   "")
4536 (define_insn "*floatsidf2_mixed"
4537   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4538         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4539   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4540   "@
4541    fild%z1\t%1
4542    #
4543    cvtsi2sd\t{%1, %0|%0, %1}
4544    cvtsi2sd\t{%1, %0|%0, %1}"
4545   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4546    (set_attr "mode" "DF")
4547    (set_attr "unit" "*,i387,*,*")
4548    (set_attr "athlon_decode" "*,*,double,direct")
4549    (set_attr "fp_int_src" "true")])
4551 (define_insn "*floatsidf2_sse"
4552   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4553         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4554   "TARGET_SSE2 && TARGET_SSE_MATH"
4555   "cvtsi2sd\t{%1, %0|%0, %1}"
4556   [(set_attr "type" "sseicvt")
4557    (set_attr "mode" "DF")
4558    (set_attr "athlon_decode" "double,direct")
4559    (set_attr "fp_int_src" "true")])
4561 (define_insn "*floatsidf2_i387"
4562   [(set (match_operand:DF 0 "register_operand" "=f,f")
4563         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4564   "TARGET_80387"
4565   "@
4566    fild%z1\t%1
4567    #"
4568   [(set_attr "type" "fmov,multi")
4569    (set_attr "mode" "DF")
4570    (set_attr "unit" "*,i387")
4571    (set_attr "fp_int_src" "true")])
4573 (define_expand "floatdidf2"
4574   [(set (match_operand:DF 0 "register_operand" "")
4575         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4576   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4577   "")
4579 (define_insn "*floatdidf2_mixed"
4580   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4581         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4582   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4583   "@
4584    fild%z1\t%1
4585    #
4586    cvtsi2sd{q}\t{%1, %0|%0, %1}
4587    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4588   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4589    (set_attr "mode" "DF")
4590    (set_attr "unit" "*,i387,*,*")
4591    (set_attr "athlon_decode" "*,*,double,direct")
4592    (set_attr "fp_int_src" "true")])
4594 (define_insn "*floatdidf2_sse"
4595   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4596         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4597   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4598   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4599   [(set_attr "type" "sseicvt")
4600    (set_attr "mode" "DF")
4601    (set_attr "athlon_decode" "double,direct")
4602    (set_attr "fp_int_src" "true")])
4604 (define_insn "*floatdidf2_i387"
4605   [(set (match_operand:DF 0 "register_operand" "=f,f")
4606         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4607   "TARGET_80387"
4608   "@
4609    fild%z1\t%1
4610    #"
4611   [(set_attr "type" "fmov,multi")
4612    (set_attr "mode" "DF")
4613    (set_attr "unit" "*,i387")
4614    (set_attr "fp_int_src" "true")])
4616 (define_insn "floathixf2"
4617   [(set (match_operand:XF 0 "register_operand" "=f,f")
4618         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4619   "TARGET_80387"
4620   "@
4621    fild%z1\t%1
4622    #"
4623   [(set_attr "type" "fmov,multi")
4624    (set_attr "mode" "XF")
4625    (set_attr "unit" "*,i387")
4626    (set_attr "fp_int_src" "true")])
4628 (define_insn "floatsixf2"
4629   [(set (match_operand:XF 0 "register_operand" "=f,f")
4630         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4631   "TARGET_80387"
4632   "@
4633    fild%z1\t%1
4634    #"
4635   [(set_attr "type" "fmov,multi")
4636    (set_attr "mode" "XF")
4637    (set_attr "unit" "*,i387")
4638    (set_attr "fp_int_src" "true")])
4640 (define_insn "floatdixf2"
4641   [(set (match_operand:XF 0 "register_operand" "=f,f")
4642         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4643   "TARGET_80387"
4644   "@
4645    fild%z1\t%1
4646    #"
4647   [(set_attr "type" "fmov,multi")
4648    (set_attr "mode" "XF")
4649    (set_attr "unit" "*,i387")
4650    (set_attr "fp_int_src" "true")])
4652 ;; %%% Kill these when reload knows how to do it.
4653 (define_split
4654   [(set (match_operand 0 "fp_register_operand" "")
4655         (float (match_operand 1 "register_operand" "")))]
4656   "reload_completed
4657    && TARGET_80387
4658    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4659   [(const_int 0)]
4661   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4662   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4663   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4664   ix86_free_from_memory (GET_MODE (operands[1]));
4665   DONE;
4668 (define_expand "floatunssisf2"
4669   [(use (match_operand:SF 0 "register_operand" ""))
4670    (use (match_operand:SI 1 "register_operand" ""))]
4671   "!TARGET_64BIT && TARGET_SSE_MATH"
4672   "x86_emit_floatuns (operands); DONE;")
4674 (define_expand "floatunsdisf2"
4675   [(use (match_operand:SF 0 "register_operand" ""))
4676    (use (match_operand:DI 1 "register_operand" ""))]
4677   "TARGET_64BIT && TARGET_SSE_MATH"
4678   "x86_emit_floatuns (operands); DONE;")
4680 (define_expand "floatunsdidf2"
4681   [(use (match_operand:DF 0 "register_operand" ""))
4682    (use (match_operand:DI 1 "register_operand" ""))]
4683   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4684   "x86_emit_floatuns (operands); DONE;")
4686 ;; SSE extract/set expanders
4689 ;; Add instructions
4691 ;; %%% splits for addsidi3
4692 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4693 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4694 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4696 (define_expand "adddi3"
4697   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4698         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4699                  (match_operand:DI 2 "x86_64_general_operand" "")))
4700    (clobber (reg:CC FLAGS_REG))]
4701   ""
4702   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4704 (define_insn "*adddi3_1"
4705   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4706         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4707                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4708    (clobber (reg:CC FLAGS_REG))]
4709   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4710   "#")
4712 (define_split
4713   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4714         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4715                  (match_operand:DI 2 "general_operand" "")))
4716    (clobber (reg:CC FLAGS_REG))]
4717   "!TARGET_64BIT && reload_completed"
4718   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4719                                           UNSPEC_ADD_CARRY))
4720               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4721    (parallel [(set (match_dup 3)
4722                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4723                                      (match_dup 4))
4724                             (match_dup 5)))
4725               (clobber (reg:CC FLAGS_REG))])]
4726   "split_di (operands+0, 1, operands+0, operands+3);
4727    split_di (operands+1, 1, operands+1, operands+4);
4728    split_di (operands+2, 1, operands+2, operands+5);")
4730 (define_insn "adddi3_carry_rex64"
4731   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4732           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4733                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4734                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4735    (clobber (reg:CC FLAGS_REG))]
4736   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4737   "adc{q}\t{%2, %0|%0, %2}"
4738   [(set_attr "type" "alu")
4739    (set_attr "pent_pair" "pu")
4740    (set_attr "mode" "DI")])
4742 (define_insn "*adddi3_cc_rex64"
4743   [(set (reg:CC FLAGS_REG)
4744         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4745                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4746                    UNSPEC_ADD_CARRY))
4747    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4748         (plus:DI (match_dup 1) (match_dup 2)))]
4749   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4750   "add{q}\t{%2, %0|%0, %2}"
4751   [(set_attr "type" "alu")
4752    (set_attr "mode" "DI")])
4754 (define_insn "addqi3_carry"
4755   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4756           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4757                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4758                    (match_operand:QI 2 "general_operand" "qi,qm")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4761   "adc{b}\t{%2, %0|%0, %2}"
4762   [(set_attr "type" "alu")
4763    (set_attr "pent_pair" "pu")
4764    (set_attr "mode" "QI")])
4766 (define_insn "addhi3_carry"
4767   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4768           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4769                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4770                    (match_operand:HI 2 "general_operand" "ri,rm")))
4771    (clobber (reg:CC FLAGS_REG))]
4772   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4773   "adc{w}\t{%2, %0|%0, %2}"
4774   [(set_attr "type" "alu")
4775    (set_attr "pent_pair" "pu")
4776    (set_attr "mode" "HI")])
4778 (define_insn "addsi3_carry"
4779   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4780           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4781                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4782                    (match_operand:SI 2 "general_operand" "ri,rm")))
4783    (clobber (reg:CC FLAGS_REG))]
4784   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4785   "adc{l}\t{%2, %0|%0, %2}"
4786   [(set_attr "type" "alu")
4787    (set_attr "pent_pair" "pu")
4788    (set_attr "mode" "SI")])
4790 (define_insn "*addsi3_carry_zext"
4791   [(set (match_operand:DI 0 "register_operand" "=r")
4792           (zero_extend:DI 
4793             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4794                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4795                      (match_operand:SI 2 "general_operand" "rim"))))
4796    (clobber (reg:CC FLAGS_REG))]
4797   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4798   "adc{l}\t{%2, %k0|%k0, %2}"
4799   [(set_attr "type" "alu")
4800    (set_attr "pent_pair" "pu")
4801    (set_attr "mode" "SI")])
4803 (define_insn "*addsi3_cc"
4804   [(set (reg:CC FLAGS_REG)
4805         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4806                     (match_operand:SI 2 "general_operand" "ri,rm")]
4807                    UNSPEC_ADD_CARRY))
4808    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4809         (plus:SI (match_dup 1) (match_dup 2)))]
4810   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4811   "add{l}\t{%2, %0|%0, %2}"
4812   [(set_attr "type" "alu")
4813    (set_attr "mode" "SI")])
4815 (define_insn "addqi3_cc"
4816   [(set (reg:CC FLAGS_REG)
4817         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4818                     (match_operand:QI 2 "general_operand" "qi,qm")]
4819                    UNSPEC_ADD_CARRY))
4820    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4821         (plus:QI (match_dup 1) (match_dup 2)))]
4822   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4823   "add{b}\t{%2, %0|%0, %2}"
4824   [(set_attr "type" "alu")
4825    (set_attr "mode" "QI")])
4827 (define_expand "addsi3"
4828   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4829                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4830                             (match_operand:SI 2 "general_operand" "")))
4831               (clobber (reg:CC FLAGS_REG))])]
4832   ""
4833   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4835 (define_insn "*lea_1"
4836   [(set (match_operand:SI 0 "register_operand" "=r")
4837         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4838   "!TARGET_64BIT"
4839   "lea{l}\t{%a1, %0|%0, %a1}"
4840   [(set_attr "type" "lea")
4841    (set_attr "mode" "SI")])
4843 (define_insn "*lea_1_rex64"
4844   [(set (match_operand:SI 0 "register_operand" "=r")
4845         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4846   "TARGET_64BIT"
4847   "lea{l}\t{%a1, %0|%0, %a1}"
4848   [(set_attr "type" "lea")
4849    (set_attr "mode" "SI")])
4851 (define_insn "*lea_1_zext"
4852   [(set (match_operand:DI 0 "register_operand" "=r")
4853         (zero_extend:DI
4854          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4855   "TARGET_64BIT"
4856   "lea{l}\t{%a1, %k0|%k0, %a1}"
4857   [(set_attr "type" "lea")
4858    (set_attr "mode" "SI")])
4860 (define_insn "*lea_2_rex64"
4861   [(set (match_operand:DI 0 "register_operand" "=r")
4862         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4863   "TARGET_64BIT"
4864   "lea{q}\t{%a1, %0|%0, %a1}"
4865   [(set_attr "type" "lea")
4866    (set_attr "mode" "DI")])
4868 ;; The lea patterns for non-Pmodes needs to be matched by several
4869 ;; insns converted to real lea by splitters.
4871 (define_insn_and_split "*lea_general_1"
4872   [(set (match_operand 0 "register_operand" "=r")
4873         (plus (plus (match_operand 1 "index_register_operand" "l")
4874                     (match_operand 2 "register_operand" "r"))
4875               (match_operand 3 "immediate_operand" "i")))]
4876   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4877     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4878    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4879    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4880    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4881    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4882        || GET_MODE (operands[3]) == VOIDmode)"
4883   "#"
4884   "&& reload_completed"
4885   [(const_int 0)]
4887   rtx pat;
4888   operands[0] = gen_lowpart (SImode, operands[0]);
4889   operands[1] = gen_lowpart (Pmode, operands[1]);
4890   operands[2] = gen_lowpart (Pmode, operands[2]);
4891   operands[3] = gen_lowpart (Pmode, operands[3]);
4892   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4893                       operands[3]);
4894   if (Pmode != SImode)
4895     pat = gen_rtx_SUBREG (SImode, pat, 0);
4896   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4897   DONE;
4899   [(set_attr "type" "lea")
4900    (set_attr "mode" "SI")])
4902 (define_insn_and_split "*lea_general_1_zext"
4903   [(set (match_operand:DI 0 "register_operand" "=r")
4904         (zero_extend:DI
4905           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4906                             (match_operand:SI 2 "register_operand" "r"))
4907                    (match_operand:SI 3 "immediate_operand" "i"))))]
4908   "TARGET_64BIT"
4909   "#"
4910   "&& reload_completed"
4911   [(set (match_dup 0)
4912         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4913                                                      (match_dup 2))
4914                                             (match_dup 3)) 0)))]
4916   operands[1] = gen_lowpart (Pmode, operands[1]);
4917   operands[2] = gen_lowpart (Pmode, operands[2]);
4918   operands[3] = gen_lowpart (Pmode, operands[3]);
4920   [(set_attr "type" "lea")
4921    (set_attr "mode" "SI")])
4923 (define_insn_and_split "*lea_general_2"
4924   [(set (match_operand 0 "register_operand" "=r")
4925         (plus (mult (match_operand 1 "index_register_operand" "l")
4926                     (match_operand 2 "const248_operand" "i"))
4927               (match_operand 3 "nonmemory_operand" "ri")))]
4928   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4929     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4930    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4931    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4932    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4933        || GET_MODE (operands[3]) == VOIDmode)"
4934   "#"
4935   "&& reload_completed"
4936   [(const_int 0)]
4938   rtx pat;
4939   operands[0] = gen_lowpart (SImode, operands[0]);
4940   operands[1] = gen_lowpart (Pmode, operands[1]);
4941   operands[3] = gen_lowpart (Pmode, operands[3]);
4942   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4943                       operands[3]);
4944   if (Pmode != SImode)
4945     pat = gen_rtx_SUBREG (SImode, pat, 0);
4946   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4947   DONE;
4949   [(set_attr "type" "lea")
4950    (set_attr "mode" "SI")])
4952 (define_insn_and_split "*lea_general_2_zext"
4953   [(set (match_operand:DI 0 "register_operand" "=r")
4954         (zero_extend:DI
4955           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4956                             (match_operand:SI 2 "const248_operand" "n"))
4957                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4958   "TARGET_64BIT"
4959   "#"
4960   "&& reload_completed"
4961   [(set (match_dup 0)
4962         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4963                                                      (match_dup 2))
4964                                             (match_dup 3)) 0)))]
4966   operands[1] = gen_lowpart (Pmode, operands[1]);
4967   operands[3] = gen_lowpart (Pmode, operands[3]);
4969   [(set_attr "type" "lea")
4970    (set_attr "mode" "SI")])
4972 (define_insn_and_split "*lea_general_3"
4973   [(set (match_operand 0 "register_operand" "=r")
4974         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4975                           (match_operand 2 "const248_operand" "i"))
4976                     (match_operand 3 "register_operand" "r"))
4977               (match_operand 4 "immediate_operand" "i")))]
4978   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4979     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4980    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4981    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4982    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4983   "#"
4984   "&& reload_completed"
4985   [(const_int 0)]
4987   rtx pat;
4988   operands[0] = gen_lowpart (SImode, operands[0]);
4989   operands[1] = gen_lowpart (Pmode, operands[1]);
4990   operands[3] = gen_lowpart (Pmode, operands[3]);
4991   operands[4] = gen_lowpart (Pmode, operands[4]);
4992   pat = gen_rtx_PLUS (Pmode,
4993                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
4994                                                          operands[2]),
4995                                     operands[3]),
4996                       operands[4]);
4997   if (Pmode != SImode)
4998     pat = gen_rtx_SUBREG (SImode, pat, 0);
4999   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5000   DONE;
5002   [(set_attr "type" "lea")
5003    (set_attr "mode" "SI")])
5005 (define_insn_and_split "*lea_general_3_zext"
5006   [(set (match_operand:DI 0 "register_operand" "=r")
5007         (zero_extend:DI
5008           (plus:SI (plus:SI (mult:SI
5009                               (match_operand:SI 1 "index_register_operand" "l")
5010                               (match_operand:SI 2 "const248_operand" "n"))
5011                             (match_operand:SI 3 "register_operand" "r"))
5012                    (match_operand:SI 4 "immediate_operand" "i"))))]
5013   "TARGET_64BIT"
5014   "#"
5015   "&& reload_completed"
5016   [(set (match_dup 0)
5017         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5018                                                               (match_dup 2))
5019                                                      (match_dup 3))
5020                                             (match_dup 4)) 0)))]
5022   operands[1] = gen_lowpart (Pmode, operands[1]);
5023   operands[3] = gen_lowpart (Pmode, operands[3]);
5024   operands[4] = gen_lowpart (Pmode, operands[4]);
5026   [(set_attr "type" "lea")
5027    (set_attr "mode" "SI")])
5029 (define_insn "*adddi_1_rex64"
5030   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5031         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5032                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5033    (clobber (reg:CC FLAGS_REG))]
5034   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5036   switch (get_attr_type (insn))
5037     {
5038     case TYPE_LEA:
5039       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5040       return "lea{q}\t{%a2, %0|%0, %a2}";
5042     case TYPE_INCDEC:
5043       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5044       if (operands[2] == const1_rtx)
5045         return "inc{q}\t%0";
5046       else
5047         {
5048           gcc_assert (operands[2] == constm1_rtx);
5049           return "dec{q}\t%0";
5050         }
5052     default:
5053       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5055       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5056          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5057       if (GET_CODE (operands[2]) == CONST_INT
5058           /* Avoid overflows.  */
5059           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5060           && (INTVAL (operands[2]) == 128
5061               || (INTVAL (operands[2]) < 0
5062                   && INTVAL (operands[2]) != -128)))
5063         {
5064           operands[2] = GEN_INT (-INTVAL (operands[2]));
5065           return "sub{q}\t{%2, %0|%0, %2}";
5066         }
5067       return "add{q}\t{%2, %0|%0, %2}";
5068     }
5070   [(set (attr "type")
5071      (cond [(eq_attr "alternative" "2")
5072               (const_string "lea")
5073             ; Current assemblers are broken and do not allow @GOTOFF in
5074             ; ought but a memory context.
5075             (match_operand:DI 2 "pic_symbolic_operand" "")
5076               (const_string "lea")
5077             (match_operand:DI 2 "incdec_operand" "")
5078               (const_string "incdec")
5079            ]
5080            (const_string "alu")))
5081    (set_attr "mode" "DI")])
5083 ;; Convert lea to the lea pattern to avoid flags dependency.
5084 (define_split
5085   [(set (match_operand:DI 0 "register_operand" "")
5086         (plus:DI (match_operand:DI 1 "register_operand" "")
5087                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5088    (clobber (reg:CC FLAGS_REG))]
5089   "TARGET_64BIT && reload_completed
5090    && true_regnum (operands[0]) != true_regnum (operands[1])"
5091   [(set (match_dup 0)
5092         (plus:DI (match_dup 1)
5093                  (match_dup 2)))]
5094   "")
5096 (define_insn "*adddi_2_rex64"
5097   [(set (reg FLAGS_REG)
5098         (compare
5099           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5100                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5101           (const_int 0)))                       
5102    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5103         (plus:DI (match_dup 1) (match_dup 2)))]
5104   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5105    && ix86_binary_operator_ok (PLUS, DImode, operands)
5106    /* Current assemblers are broken and do not allow @GOTOFF in
5107       ought but a memory context.  */
5108    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5110   switch (get_attr_type (insn))
5111     {
5112     case TYPE_INCDEC:
5113       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5114       if (operands[2] == const1_rtx)
5115         return "inc{q}\t%0";
5116       else
5117         {
5118           gcc_assert (operands[2] == constm1_rtx);
5119           return "dec{q}\t%0";
5120         }
5122     default:
5123       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5124       /* ???? We ought to handle there the 32bit case too
5125          - do we need new constraint?  */
5126       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5127          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5128       if (GET_CODE (operands[2]) == CONST_INT
5129           /* Avoid overflows.  */
5130           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5131           && (INTVAL (operands[2]) == 128
5132               || (INTVAL (operands[2]) < 0
5133                   && INTVAL (operands[2]) != -128)))
5134         {
5135           operands[2] = GEN_INT (-INTVAL (operands[2]));
5136           return "sub{q}\t{%2, %0|%0, %2}";
5137         }
5138       return "add{q}\t{%2, %0|%0, %2}";
5139     }
5141   [(set (attr "type")
5142      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5143         (const_string "incdec")
5144         (const_string "alu")))
5145    (set_attr "mode" "DI")])
5147 (define_insn "*adddi_3_rex64"
5148   [(set (reg FLAGS_REG)
5149         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5150                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5151    (clobber (match_scratch:DI 0 "=r"))]
5152   "TARGET_64BIT
5153    && ix86_match_ccmode (insn, CCZmode)
5154    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5155    /* Current assemblers are broken and do not allow @GOTOFF in
5156       ought but a memory context.  */
5157    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5159   switch (get_attr_type (insn))
5160     {
5161     case TYPE_INCDEC:
5162       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5163       if (operands[2] == const1_rtx)
5164         return "inc{q}\t%0";
5165       else
5166         {
5167           gcc_assert (operands[2] == constm1_rtx);
5168           return "dec{q}\t%0";
5169         }
5171     default:
5172       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5173       /* ???? We ought to handle there the 32bit case too
5174          - do we need new constraint?  */
5175       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5176          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5177       if (GET_CODE (operands[2]) == CONST_INT
5178           /* Avoid overflows.  */
5179           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5180           && (INTVAL (operands[2]) == 128
5181               || (INTVAL (operands[2]) < 0
5182                   && INTVAL (operands[2]) != -128)))
5183         {
5184           operands[2] = GEN_INT (-INTVAL (operands[2]));
5185           return "sub{q}\t{%2, %0|%0, %2}";
5186         }
5187       return "add{q}\t{%2, %0|%0, %2}";
5188     }
5190   [(set (attr "type")
5191      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5192         (const_string "incdec")
5193         (const_string "alu")))
5194    (set_attr "mode" "DI")])
5196 ; For comparisons against 1, -1 and 128, we may generate better code
5197 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5198 ; is matched then.  We can't accept general immediate, because for
5199 ; case of overflows,  the result is messed up.
5200 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5201 ; when negated.
5202 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5203 ; only for comparisons not depending on it.
5204 (define_insn "*adddi_4_rex64"
5205   [(set (reg FLAGS_REG)
5206         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5207                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5208    (clobber (match_scratch:DI 0 "=rm"))]
5209   "TARGET_64BIT
5210    &&  ix86_match_ccmode (insn, CCGCmode)"
5212   switch (get_attr_type (insn))
5213     {
5214     case TYPE_INCDEC:
5215       if (operands[2] == constm1_rtx)
5216         return "inc{q}\t%0";
5217       else
5218         {
5219           gcc_assert (operands[2] == const1_rtx);
5220           return "dec{q}\t%0";
5221         }
5223     default:
5224       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5225       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5226          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5227       if ((INTVAL (operands[2]) == -128
5228            || (INTVAL (operands[2]) > 0
5229                && INTVAL (operands[2]) != 128))
5230           /* Avoid overflows.  */
5231           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5232         return "sub{q}\t{%2, %0|%0, %2}";
5233       operands[2] = GEN_INT (-INTVAL (operands[2]));
5234       return "add{q}\t{%2, %0|%0, %2}";
5235     }
5237   [(set (attr "type")
5238      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5239         (const_string "incdec")
5240         (const_string "alu")))
5241    (set_attr "mode" "DI")])
5243 (define_insn "*adddi_5_rex64"
5244   [(set (reg FLAGS_REG)
5245         (compare
5246           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5247                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5248           (const_int 0)))                       
5249    (clobber (match_scratch:DI 0 "=r"))]
5250   "TARGET_64BIT
5251    && ix86_match_ccmode (insn, CCGOCmode)
5252    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5253    /* Current assemblers are broken and do not allow @GOTOFF in
5254       ought but a memory context.  */
5255    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5257   switch (get_attr_type (insn))
5258     {
5259     case TYPE_INCDEC:
5260       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5261       if (operands[2] == const1_rtx)
5262         return "inc{q}\t%0";
5263       else
5264         {
5265           gcc_assert (operands[2] == constm1_rtx);
5266           return "dec{q}\t%0";
5267         }
5269     default:
5270       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5271       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5272          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5273       if (GET_CODE (operands[2]) == CONST_INT
5274           /* Avoid overflows.  */
5275           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5276           && (INTVAL (operands[2]) == 128
5277               || (INTVAL (operands[2]) < 0
5278                   && INTVAL (operands[2]) != -128)))
5279         {
5280           operands[2] = GEN_INT (-INTVAL (operands[2]));
5281           return "sub{q}\t{%2, %0|%0, %2}";
5282         }
5283       return "add{q}\t{%2, %0|%0, %2}";
5284     }
5286   [(set (attr "type")
5287      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5288         (const_string "incdec")
5289         (const_string "alu")))
5290    (set_attr "mode" "DI")])
5293 (define_insn "*addsi_1"
5294   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5295         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5296                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5297    (clobber (reg:CC FLAGS_REG))]
5298   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5300   switch (get_attr_type (insn))
5301     {
5302     case TYPE_LEA:
5303       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5304       return "lea{l}\t{%a2, %0|%0, %a2}";
5306     case TYPE_INCDEC:
5307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5308       if (operands[2] == const1_rtx)
5309         return "inc{l}\t%0";
5310       else
5311         {
5312           gcc_assert (operands[2] == constm1_rtx);
5313           return "dec{l}\t%0";
5314         }
5316     default:
5317       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5319       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5320          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5321       if (GET_CODE (operands[2]) == CONST_INT
5322           && (INTVAL (operands[2]) == 128
5323               || (INTVAL (operands[2]) < 0
5324                   && INTVAL (operands[2]) != -128)))
5325         {
5326           operands[2] = GEN_INT (-INTVAL (operands[2]));
5327           return "sub{l}\t{%2, %0|%0, %2}";
5328         }
5329       return "add{l}\t{%2, %0|%0, %2}";
5330     }
5332   [(set (attr "type")
5333      (cond [(eq_attr "alternative" "2")
5334               (const_string "lea")
5335             ; Current assemblers are broken and do not allow @GOTOFF in
5336             ; ought but a memory context.
5337             (match_operand:SI 2 "pic_symbolic_operand" "")
5338               (const_string "lea")
5339             (match_operand:SI 2 "incdec_operand" "")
5340               (const_string "incdec")
5341            ]
5342            (const_string "alu")))
5343    (set_attr "mode" "SI")])
5345 ;; Convert lea to the lea pattern to avoid flags dependency.
5346 (define_split
5347   [(set (match_operand 0 "register_operand" "")
5348         (plus (match_operand 1 "register_operand" "")
5349               (match_operand 2 "nonmemory_operand" "")))
5350    (clobber (reg:CC FLAGS_REG))]
5351   "reload_completed
5352    && true_regnum (operands[0]) != true_regnum (operands[1])"
5353   [(const_int 0)]
5355   rtx pat;
5356   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5357      may confuse gen_lowpart.  */
5358   if (GET_MODE (operands[0]) != Pmode)
5359     {
5360       operands[1] = gen_lowpart (Pmode, operands[1]);
5361       operands[2] = gen_lowpart (Pmode, operands[2]);
5362     }
5363   operands[0] = gen_lowpart (SImode, operands[0]);
5364   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5365   if (Pmode != SImode)
5366     pat = gen_rtx_SUBREG (SImode, pat, 0);
5367   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5368   DONE;
5371 ;; It may seem that nonimmediate operand is proper one for operand 1.
5372 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5373 ;; we take care in ix86_binary_operator_ok to not allow two memory
5374 ;; operands so proper swapping will be done in reload.  This allow
5375 ;; patterns constructed from addsi_1 to match.
5376 (define_insn "addsi_1_zext"
5377   [(set (match_operand:DI 0 "register_operand" "=r,r")
5378         (zero_extend:DI
5379           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5380                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5381    (clobber (reg:CC FLAGS_REG))]
5382   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5384   switch (get_attr_type (insn))
5385     {
5386     case TYPE_LEA:
5387       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5388       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5390     case TYPE_INCDEC:
5391       if (operands[2] == const1_rtx)
5392         return "inc{l}\t%k0";
5393       else
5394         {
5395           gcc_assert (operands[2] == constm1_rtx);
5396           return "dec{l}\t%k0";
5397         }
5399     default:
5400       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5401          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5402       if (GET_CODE (operands[2]) == CONST_INT
5403           && (INTVAL (operands[2]) == 128
5404               || (INTVAL (operands[2]) < 0
5405                   && INTVAL (operands[2]) != -128)))
5406         {
5407           operands[2] = GEN_INT (-INTVAL (operands[2]));
5408           return "sub{l}\t{%2, %k0|%k0, %2}";
5409         }
5410       return "add{l}\t{%2, %k0|%k0, %2}";
5411     }
5413   [(set (attr "type")
5414      (cond [(eq_attr "alternative" "1")
5415               (const_string "lea")
5416             ; Current assemblers are broken and do not allow @GOTOFF in
5417             ; ought but a memory context.
5418             (match_operand:SI 2 "pic_symbolic_operand" "")
5419               (const_string "lea")
5420             (match_operand:SI 2 "incdec_operand" "")
5421               (const_string "incdec")
5422            ]
5423            (const_string "alu")))
5424    (set_attr "mode" "SI")])
5426 ;; Convert lea to the lea pattern to avoid flags dependency.
5427 (define_split
5428   [(set (match_operand:DI 0 "register_operand" "")
5429         (zero_extend:DI
5430           (plus:SI (match_operand:SI 1 "register_operand" "")
5431                    (match_operand:SI 2 "nonmemory_operand" ""))))
5432    (clobber (reg:CC FLAGS_REG))]
5433   "TARGET_64BIT && reload_completed
5434    && true_regnum (operands[0]) != true_regnum (operands[1])"
5435   [(set (match_dup 0)
5436         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5438   operands[1] = gen_lowpart (Pmode, operands[1]);
5439   operands[2] = gen_lowpart (Pmode, operands[2]);
5442 (define_insn "*addsi_2"
5443   [(set (reg FLAGS_REG)
5444         (compare
5445           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5446                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5447           (const_int 0)))                       
5448    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5449         (plus:SI (match_dup 1) (match_dup 2)))]
5450   "ix86_match_ccmode (insn, CCGOCmode)
5451    && ix86_binary_operator_ok (PLUS, SImode, operands)
5452    /* Current assemblers are broken and do not allow @GOTOFF in
5453       ought but a memory context.  */
5454    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5456   switch (get_attr_type (insn))
5457     {
5458     case TYPE_INCDEC:
5459       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5460       if (operands[2] == const1_rtx)
5461         return "inc{l}\t%0";
5462       else
5463         {
5464           gcc_assert (operands[2] == constm1_rtx);
5465           return "dec{l}\t%0";
5466         }
5468     default:
5469       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5470       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5471          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5472       if (GET_CODE (operands[2]) == CONST_INT
5473           && (INTVAL (operands[2]) == 128
5474               || (INTVAL (operands[2]) < 0
5475                   && INTVAL (operands[2]) != -128)))
5476         {
5477           operands[2] = GEN_INT (-INTVAL (operands[2]));
5478           return "sub{l}\t{%2, %0|%0, %2}";
5479         }
5480       return "add{l}\t{%2, %0|%0, %2}";
5481     }
5483   [(set (attr "type")
5484      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5485         (const_string "incdec")
5486         (const_string "alu")))
5487    (set_attr "mode" "SI")])
5489 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5490 (define_insn "*addsi_2_zext"
5491   [(set (reg FLAGS_REG)
5492         (compare
5493           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5494                    (match_operand:SI 2 "general_operand" "rmni"))
5495           (const_int 0)))                       
5496    (set (match_operand:DI 0 "register_operand" "=r")
5497         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5498   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5499    && ix86_binary_operator_ok (PLUS, SImode, operands)
5500    /* Current assemblers are broken and do not allow @GOTOFF in
5501       ought but a memory context.  */
5502    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5504   switch (get_attr_type (insn))
5505     {
5506     case TYPE_INCDEC:
5507       if (operands[2] == const1_rtx)
5508         return "inc{l}\t%k0";
5509       else
5510         {
5511           gcc_assert (operands[2] == constm1_rtx);
5512           return "dec{l}\t%k0";
5513         }
5515     default:
5516       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5517          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5518       if (GET_CODE (operands[2]) == CONST_INT
5519           && (INTVAL (operands[2]) == 128
5520               || (INTVAL (operands[2]) < 0
5521                   && INTVAL (operands[2]) != -128)))
5522         {
5523           operands[2] = GEN_INT (-INTVAL (operands[2]));
5524           return "sub{l}\t{%2, %k0|%k0, %2}";
5525         }
5526       return "add{l}\t{%2, %k0|%k0, %2}";
5527     }
5529   [(set (attr "type")
5530      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5531         (const_string "incdec")
5532         (const_string "alu")))
5533    (set_attr "mode" "SI")])
5535 (define_insn "*addsi_3"
5536   [(set (reg FLAGS_REG)
5537         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5538                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5539    (clobber (match_scratch:SI 0 "=r"))]
5540   "ix86_match_ccmode (insn, CCZmode)
5541    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5542    /* Current assemblers are broken and do not allow @GOTOFF in
5543       ought but a memory context.  */
5544    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5546   switch (get_attr_type (insn))
5547     {
5548     case TYPE_INCDEC:
5549       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5550       if (operands[2] == const1_rtx)
5551         return "inc{l}\t%0";
5552       else
5553         {
5554           gcc_assert (operands[2] == constm1_rtx);
5555           return "dec{l}\t%0";
5556         }
5558     default:
5559       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5560       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5561          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5562       if (GET_CODE (operands[2]) == CONST_INT
5563           && (INTVAL (operands[2]) == 128
5564               || (INTVAL (operands[2]) < 0
5565                   && INTVAL (operands[2]) != -128)))
5566         {
5567           operands[2] = GEN_INT (-INTVAL (operands[2]));
5568           return "sub{l}\t{%2, %0|%0, %2}";
5569         }
5570       return "add{l}\t{%2, %0|%0, %2}";
5571     }
5573   [(set (attr "type")
5574      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5575         (const_string "incdec")
5576         (const_string "alu")))
5577    (set_attr "mode" "SI")])
5579 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5580 (define_insn "*addsi_3_zext"
5581   [(set (reg FLAGS_REG)
5582         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5583                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5584    (set (match_operand:DI 0 "register_operand" "=r")
5585         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5586   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5587    && ix86_binary_operator_ok (PLUS, SImode, operands)
5588    /* Current assemblers are broken and do not allow @GOTOFF in
5589       ought but a memory context.  */
5590    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5592   switch (get_attr_type (insn))
5593     {
5594     case TYPE_INCDEC:
5595       if (operands[2] == const1_rtx)
5596         return "inc{l}\t%k0";
5597       else
5598         {
5599           gcc_assert (operands[2] == constm1_rtx);
5600           return "dec{l}\t%k0";
5601         }
5603     default:
5604       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5605          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5606       if (GET_CODE (operands[2]) == CONST_INT
5607           && (INTVAL (operands[2]) == 128
5608               || (INTVAL (operands[2]) < 0
5609                   && INTVAL (operands[2]) != -128)))
5610         {
5611           operands[2] = GEN_INT (-INTVAL (operands[2]));
5612           return "sub{l}\t{%2, %k0|%k0, %2}";
5613         }
5614       return "add{l}\t{%2, %k0|%k0, %2}";
5615     }
5617   [(set (attr "type")
5618      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5619         (const_string "incdec")
5620         (const_string "alu")))
5621    (set_attr "mode" "SI")])
5623 ; For comparisons against 1, -1 and 128, we may generate better code
5624 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5625 ; is matched then.  We can't accept general immediate, because for
5626 ; case of overflows,  the result is messed up.
5627 ; This pattern also don't hold of 0x80000000, since the value overflows
5628 ; when negated.
5629 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5630 ; only for comparisons not depending on it.
5631 (define_insn "*addsi_4"
5632   [(set (reg FLAGS_REG)
5633         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5634                  (match_operand:SI 2 "const_int_operand" "n")))
5635    (clobber (match_scratch:SI 0 "=rm"))]
5636   "ix86_match_ccmode (insn, CCGCmode)
5637    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5639   switch (get_attr_type (insn))
5640     {
5641     case TYPE_INCDEC:
5642       if (operands[2] == constm1_rtx)
5643         return "inc{l}\t%0";
5644       else
5645         {
5646           gcc_assert (operands[2] == const1_rtx);
5647           return "dec{l}\t%0";
5648         }
5650     default:
5651       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5652       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5653          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5654       if ((INTVAL (operands[2]) == -128
5655            || (INTVAL (operands[2]) > 0
5656                && INTVAL (operands[2]) != 128)))
5657         return "sub{l}\t{%2, %0|%0, %2}";
5658       operands[2] = GEN_INT (-INTVAL (operands[2]));
5659       return "add{l}\t{%2, %0|%0, %2}";
5660     }
5662   [(set (attr "type")
5663      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5664         (const_string "incdec")
5665         (const_string "alu")))
5666    (set_attr "mode" "SI")])
5668 (define_insn "*addsi_5"
5669   [(set (reg FLAGS_REG)
5670         (compare
5671           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5672                    (match_operand:SI 2 "general_operand" "rmni"))
5673           (const_int 0)))                       
5674    (clobber (match_scratch:SI 0 "=r"))]
5675   "ix86_match_ccmode (insn, CCGOCmode)
5676    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5677    /* Current assemblers are broken and do not allow @GOTOFF in
5678       ought but a memory context.  */
5679    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5681   switch (get_attr_type (insn))
5682     {
5683     case TYPE_INCDEC:
5684       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5685       if (operands[2] == const1_rtx)
5686         return "inc{l}\t%0";
5687       else
5688         {
5689           gcc_assert (operands[2] == constm1_rtx);
5690           return "dec{l}\t%0";
5691         }
5693     default:
5694       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5695       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5696          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5697       if (GET_CODE (operands[2]) == CONST_INT
5698           && (INTVAL (operands[2]) == 128
5699               || (INTVAL (operands[2]) < 0
5700                   && INTVAL (operands[2]) != -128)))
5701         {
5702           operands[2] = GEN_INT (-INTVAL (operands[2]));
5703           return "sub{l}\t{%2, %0|%0, %2}";
5704         }
5705       return "add{l}\t{%2, %0|%0, %2}";
5706     }
5708   [(set (attr "type")
5709      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5710         (const_string "incdec")
5711         (const_string "alu")))
5712    (set_attr "mode" "SI")])
5714 (define_expand "addhi3"
5715   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5716                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5717                             (match_operand:HI 2 "general_operand" "")))
5718               (clobber (reg:CC FLAGS_REG))])]
5719   "TARGET_HIMODE_MATH"
5720   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5722 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5723 ;; type optimizations enabled by define-splits.  This is not important
5724 ;; for PII, and in fact harmful because of partial register stalls.
5726 (define_insn "*addhi_1_lea"
5727   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5728         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5729                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5730    (clobber (reg:CC FLAGS_REG))]
5731   "!TARGET_PARTIAL_REG_STALL
5732    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5734   switch (get_attr_type (insn))
5735     {
5736     case TYPE_LEA:
5737       return "#";
5738     case TYPE_INCDEC:
5739       if (operands[2] == const1_rtx)
5740         return "inc{w}\t%0";
5741       else
5742         {
5743           gcc_assert (operands[2] == constm1_rtx);
5744           return "dec{w}\t%0";
5745         }
5747     default:
5748       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5749          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5750       if (GET_CODE (operands[2]) == CONST_INT
5751           && (INTVAL (operands[2]) == 128
5752               || (INTVAL (operands[2]) < 0
5753                   && INTVAL (operands[2]) != -128)))
5754         {
5755           operands[2] = GEN_INT (-INTVAL (operands[2]));
5756           return "sub{w}\t{%2, %0|%0, %2}";
5757         }
5758       return "add{w}\t{%2, %0|%0, %2}";
5759     }
5761   [(set (attr "type")
5762      (if_then_else (eq_attr "alternative" "2")
5763         (const_string "lea")
5764         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5765            (const_string "incdec")
5766            (const_string "alu"))))
5767    (set_attr "mode" "HI,HI,SI")])
5769 (define_insn "*addhi_1"
5770   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5771         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5772                  (match_operand:HI 2 "general_operand" "ri,rm")))
5773    (clobber (reg:CC FLAGS_REG))]
5774   "TARGET_PARTIAL_REG_STALL
5775    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5777   switch (get_attr_type (insn))
5778     {
5779     case TYPE_INCDEC:
5780       if (operands[2] == const1_rtx)
5781         return "inc{w}\t%0";
5782       else
5783         {
5784           gcc_assert (operands[2] == constm1_rtx);
5785           return "dec{w}\t%0";
5786         }
5788     default:
5789       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5790          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5791       if (GET_CODE (operands[2]) == CONST_INT
5792           && (INTVAL (operands[2]) == 128
5793               || (INTVAL (operands[2]) < 0
5794                   && INTVAL (operands[2]) != -128)))
5795         {
5796           operands[2] = GEN_INT (-INTVAL (operands[2]));
5797           return "sub{w}\t{%2, %0|%0, %2}";
5798         }
5799       return "add{w}\t{%2, %0|%0, %2}";
5800     }
5802   [(set (attr "type")
5803      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5804         (const_string "incdec")
5805         (const_string "alu")))
5806    (set_attr "mode" "HI")])
5808 (define_insn "*addhi_2"
5809   [(set (reg FLAGS_REG)
5810         (compare
5811           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5812                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5813           (const_int 0)))                       
5814    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5815         (plus:HI (match_dup 1) (match_dup 2)))]
5816   "ix86_match_ccmode (insn, CCGOCmode)
5817    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5819   switch (get_attr_type (insn))
5820     {
5821     case TYPE_INCDEC:
5822       if (operands[2] == const1_rtx)
5823         return "inc{w}\t%0";
5824       else
5825         {
5826           gcc_assert (operands[2] == constm1_rtx);
5827           return "dec{w}\t%0";
5828         }
5830     default:
5831       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5832          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5833       if (GET_CODE (operands[2]) == CONST_INT
5834           && (INTVAL (operands[2]) == 128
5835               || (INTVAL (operands[2]) < 0
5836                   && INTVAL (operands[2]) != -128)))
5837         {
5838           operands[2] = GEN_INT (-INTVAL (operands[2]));
5839           return "sub{w}\t{%2, %0|%0, %2}";
5840         }
5841       return "add{w}\t{%2, %0|%0, %2}";
5842     }
5844   [(set (attr "type")
5845      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5846         (const_string "incdec")
5847         (const_string "alu")))
5848    (set_attr "mode" "HI")])
5850 (define_insn "*addhi_3"
5851   [(set (reg FLAGS_REG)
5852         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5853                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5854    (clobber (match_scratch:HI 0 "=r"))]
5855   "ix86_match_ccmode (insn, CCZmode)
5856    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5858   switch (get_attr_type (insn))
5859     {
5860     case TYPE_INCDEC:
5861       if (operands[2] == const1_rtx)
5862         return "inc{w}\t%0";
5863       else
5864         {
5865           gcc_assert (operands[2] == constm1_rtx);
5866           return "dec{w}\t%0";
5867         }
5869     default:
5870       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5871          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5872       if (GET_CODE (operands[2]) == CONST_INT
5873           && (INTVAL (operands[2]) == 128
5874               || (INTVAL (operands[2]) < 0
5875                   && INTVAL (operands[2]) != -128)))
5876         {
5877           operands[2] = GEN_INT (-INTVAL (operands[2]));
5878           return "sub{w}\t{%2, %0|%0, %2}";
5879         }
5880       return "add{w}\t{%2, %0|%0, %2}";
5881     }
5883   [(set (attr "type")
5884      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5885         (const_string "incdec")
5886         (const_string "alu")))
5887    (set_attr "mode" "HI")])
5889 ; See comments above addsi_4 for details.
5890 (define_insn "*addhi_4"
5891   [(set (reg FLAGS_REG)
5892         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5893                  (match_operand:HI 2 "const_int_operand" "n")))
5894    (clobber (match_scratch:HI 0 "=rm"))]
5895   "ix86_match_ccmode (insn, CCGCmode)
5896    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5898   switch (get_attr_type (insn))
5899     {
5900     case TYPE_INCDEC:
5901       if (operands[2] == constm1_rtx)
5902         return "inc{w}\t%0";
5903       else
5904         {
5905           gcc_assert (operands[2] == const1_rtx);
5906           return "dec{w}\t%0";
5907         }
5909     default:
5910       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5911       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5912          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5913       if ((INTVAL (operands[2]) == -128
5914            || (INTVAL (operands[2]) > 0
5915                && INTVAL (operands[2]) != 128)))
5916         return "sub{w}\t{%2, %0|%0, %2}";
5917       operands[2] = GEN_INT (-INTVAL (operands[2]));
5918       return "add{w}\t{%2, %0|%0, %2}";
5919     }
5921   [(set (attr "type")
5922      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5923         (const_string "incdec")
5924         (const_string "alu")))
5925    (set_attr "mode" "SI")])
5928 (define_insn "*addhi_5"
5929   [(set (reg FLAGS_REG)
5930         (compare
5931           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5932                    (match_operand:HI 2 "general_operand" "rmni"))
5933           (const_int 0)))                       
5934    (clobber (match_scratch:HI 0 "=r"))]
5935   "ix86_match_ccmode (insn, CCGOCmode)
5936    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5938   switch (get_attr_type (insn))
5939     {
5940     case TYPE_INCDEC:
5941       if (operands[2] == const1_rtx)
5942         return "inc{w}\t%0";
5943       else
5944         {
5945           gcc_assert (operands[2] == constm1_rtx);
5946           return "dec{w}\t%0";
5947         }
5949     default:
5950       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5951          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5952       if (GET_CODE (operands[2]) == CONST_INT
5953           && (INTVAL (operands[2]) == 128
5954               || (INTVAL (operands[2]) < 0
5955                   && INTVAL (operands[2]) != -128)))
5956         {
5957           operands[2] = GEN_INT (-INTVAL (operands[2]));
5958           return "sub{w}\t{%2, %0|%0, %2}";
5959         }
5960       return "add{w}\t{%2, %0|%0, %2}";
5961     }
5963   [(set (attr "type")
5964      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5965         (const_string "incdec")
5966         (const_string "alu")))
5967    (set_attr "mode" "HI")])
5969 (define_expand "addqi3"
5970   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5971                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5972                             (match_operand:QI 2 "general_operand" "")))
5973               (clobber (reg:CC FLAGS_REG))])]
5974   "TARGET_QIMODE_MATH"
5975   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5977 ;; %%% Potential partial reg stall on alternative 2.  What to do?
5978 (define_insn "*addqi_1_lea"
5979   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5980         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5981                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5982    (clobber (reg:CC FLAGS_REG))]
5983   "!TARGET_PARTIAL_REG_STALL
5984    && ix86_binary_operator_ok (PLUS, QImode, operands)"
5986   int widen = (which_alternative == 2);
5987   switch (get_attr_type (insn))
5988     {
5989     case TYPE_LEA:
5990       return "#";
5991     case TYPE_INCDEC:
5992       if (operands[2] == const1_rtx)
5993         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5994       else
5995         {
5996           gcc_assert (operands[2] == constm1_rtx);
5997           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5998         }
6000     default:
6001       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003       if (GET_CODE (operands[2]) == CONST_INT
6004           && (INTVAL (operands[2]) == 128
6005               || (INTVAL (operands[2]) < 0
6006                   && INTVAL (operands[2]) != -128)))
6007         {
6008           operands[2] = GEN_INT (-INTVAL (operands[2]));
6009           if (widen)
6010             return "sub{l}\t{%2, %k0|%k0, %2}";
6011           else
6012             return "sub{b}\t{%2, %0|%0, %2}";
6013         }
6014       if (widen)
6015         return "add{l}\t{%k2, %k0|%k0, %k2}";
6016       else
6017         return "add{b}\t{%2, %0|%0, %2}";
6018     }
6020   [(set (attr "type")
6021      (if_then_else (eq_attr "alternative" "3")
6022         (const_string "lea")
6023         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6024            (const_string "incdec")
6025            (const_string "alu"))))
6026    (set_attr "mode" "QI,QI,SI,SI")])
6028 (define_insn "*addqi_1"
6029   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6030         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6031                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6032    (clobber (reg:CC FLAGS_REG))]
6033   "TARGET_PARTIAL_REG_STALL
6034    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6036   int widen = (which_alternative == 2);
6037   switch (get_attr_type (insn))
6038     {
6039     case TYPE_INCDEC:
6040       if (operands[2] == const1_rtx)
6041         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6042       else
6043         {
6044           gcc_assert (operands[2] == constm1_rtx);
6045           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6046         }
6048     default:
6049       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6050          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6051       if (GET_CODE (operands[2]) == CONST_INT
6052           && (INTVAL (operands[2]) == 128
6053               || (INTVAL (operands[2]) < 0
6054                   && INTVAL (operands[2]) != -128)))
6055         {
6056           operands[2] = GEN_INT (-INTVAL (operands[2]));
6057           if (widen)
6058             return "sub{l}\t{%2, %k0|%k0, %2}";
6059           else
6060             return "sub{b}\t{%2, %0|%0, %2}";
6061         }
6062       if (widen)
6063         return "add{l}\t{%k2, %k0|%k0, %k2}";
6064       else
6065         return "add{b}\t{%2, %0|%0, %2}";
6066     }
6068   [(set (attr "type")
6069      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6070         (const_string "incdec")
6071         (const_string "alu")))
6072    (set_attr "mode" "QI,QI,SI")])
6074 (define_insn "*addqi_1_slp"
6075   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6076         (plus:QI (match_dup 0)
6077                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6078    (clobber (reg:CC FLAGS_REG))]
6079   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6080    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6082   switch (get_attr_type (insn))
6083     {
6084     case TYPE_INCDEC:
6085       if (operands[1] == const1_rtx)
6086         return "inc{b}\t%0";
6087       else
6088         {
6089           gcc_assert (operands[1] == constm1_rtx);
6090           return "dec{b}\t%0";
6091         }
6093     default:
6094       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6095       if (GET_CODE (operands[1]) == CONST_INT
6096           && INTVAL (operands[1]) < 0)
6097         {
6098           operands[1] = GEN_INT (-INTVAL (operands[1]));
6099           return "sub{b}\t{%1, %0|%0, %1}";
6100         }
6101       return "add{b}\t{%1, %0|%0, %1}";
6102     }
6104   [(set (attr "type")
6105      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6106         (const_string "incdec")
6107         (const_string "alu1")))
6108    (set (attr "memory")
6109      (if_then_else (match_operand 1 "memory_operand" "")
6110         (const_string "load")
6111         (const_string "none")))
6112    (set_attr "mode" "QI")])
6114 (define_insn "*addqi_2"
6115   [(set (reg FLAGS_REG)
6116         (compare
6117           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6118                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6119           (const_int 0)))
6120    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6121         (plus:QI (match_dup 1) (match_dup 2)))]
6122   "ix86_match_ccmode (insn, CCGOCmode)
6123    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6125   switch (get_attr_type (insn))
6126     {
6127     case TYPE_INCDEC:
6128       if (operands[2] == const1_rtx)
6129         return "inc{b}\t%0";
6130       else
6131         {
6132           gcc_assert (operands[2] == constm1_rtx
6133                       || (GET_CODE (operands[2]) == CONST_INT
6134                           && INTVAL (operands[2]) == 255));
6135           return "dec{b}\t%0";
6136         }
6138     default:
6139       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6140       if (GET_CODE (operands[2]) == CONST_INT
6141           && INTVAL (operands[2]) < 0)
6142         {
6143           operands[2] = GEN_INT (-INTVAL (operands[2]));
6144           return "sub{b}\t{%2, %0|%0, %2}";
6145         }
6146       return "add{b}\t{%2, %0|%0, %2}";
6147     }
6149   [(set (attr "type")
6150      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6151         (const_string "incdec")
6152         (const_string "alu")))
6153    (set_attr "mode" "QI")])
6155 (define_insn "*addqi_3"
6156   [(set (reg FLAGS_REG)
6157         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6158                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6159    (clobber (match_scratch:QI 0 "=q"))]
6160   "ix86_match_ccmode (insn, CCZmode)
6161    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6163   switch (get_attr_type (insn))
6164     {
6165     case TYPE_INCDEC:
6166       if (operands[2] == const1_rtx)
6167         return "inc{b}\t%0";
6168       else
6169         {
6170           gcc_assert (operands[2] == constm1_rtx
6171                       || (GET_CODE (operands[2]) == CONST_INT
6172                           && INTVAL (operands[2]) == 255));
6173           return "dec{b}\t%0";
6174         }
6176     default:
6177       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6178       if (GET_CODE (operands[2]) == CONST_INT
6179           && INTVAL (operands[2]) < 0)
6180         {
6181           operands[2] = GEN_INT (-INTVAL (operands[2]));
6182           return "sub{b}\t{%2, %0|%0, %2}";
6183         }
6184       return "add{b}\t{%2, %0|%0, %2}";
6185     }
6187   [(set (attr "type")
6188      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6189         (const_string "incdec")
6190         (const_string "alu")))
6191    (set_attr "mode" "QI")])
6193 ; See comments above addsi_4 for details.
6194 (define_insn "*addqi_4"
6195   [(set (reg FLAGS_REG)
6196         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6197                  (match_operand:QI 2 "const_int_operand" "n")))
6198    (clobber (match_scratch:QI 0 "=qm"))]
6199   "ix86_match_ccmode (insn, CCGCmode)
6200    && (INTVAL (operands[2]) & 0xff) != 0x80"
6202   switch (get_attr_type (insn))
6203     {
6204     case TYPE_INCDEC:
6205       if (operands[2] == constm1_rtx
6206           || (GET_CODE (operands[2]) == CONST_INT
6207               && INTVAL (operands[2]) == 255))
6208         return "inc{b}\t%0";
6209       else
6210         {
6211           gcc_assert (operands[2] == const1_rtx);
6212           return "dec{b}\t%0";
6213         }
6215     default:
6216       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6217       if (INTVAL (operands[2]) < 0)
6218         {
6219           operands[2] = GEN_INT (-INTVAL (operands[2]));
6220           return "add{b}\t{%2, %0|%0, %2}";
6221         }
6222       return "sub{b}\t{%2, %0|%0, %2}";
6223     }
6225   [(set (attr "type")
6226      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6227         (const_string "incdec")
6228         (const_string "alu")))
6229    (set_attr "mode" "QI")])
6232 (define_insn "*addqi_5"
6233   [(set (reg FLAGS_REG)
6234         (compare
6235           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6236                    (match_operand:QI 2 "general_operand" "qmni"))
6237           (const_int 0)))
6238    (clobber (match_scratch:QI 0 "=q"))]
6239   "ix86_match_ccmode (insn, CCGOCmode)
6240    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6242   switch (get_attr_type (insn))
6243     {
6244     case TYPE_INCDEC:
6245       if (operands[2] == const1_rtx)
6246         return "inc{b}\t%0";
6247       else
6248         {
6249           gcc_assert (operands[2] == constm1_rtx
6250                       || (GET_CODE (operands[2]) == CONST_INT
6251                           && INTVAL (operands[2]) == 255));
6252           return "dec{b}\t%0";
6253         }
6255     default:
6256       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6257       if (GET_CODE (operands[2]) == CONST_INT
6258           && INTVAL (operands[2]) < 0)
6259         {
6260           operands[2] = GEN_INT (-INTVAL (operands[2]));
6261           return "sub{b}\t{%2, %0|%0, %2}";
6262         }
6263       return "add{b}\t{%2, %0|%0, %2}";
6264     }
6266   [(set (attr "type")
6267      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6268         (const_string "incdec")
6269         (const_string "alu")))
6270    (set_attr "mode" "QI")])
6273 (define_insn "addqi_ext_1"
6274   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6275                          (const_int 8)
6276                          (const_int 8))
6277         (plus:SI
6278           (zero_extract:SI
6279             (match_operand 1 "ext_register_operand" "0")
6280             (const_int 8)
6281             (const_int 8))
6282           (match_operand:QI 2 "general_operand" "Qmn")))
6283    (clobber (reg:CC FLAGS_REG))]
6284   "!TARGET_64BIT"
6286   switch (get_attr_type (insn))
6287     {
6288     case TYPE_INCDEC:
6289       if (operands[2] == const1_rtx)
6290         return "inc{b}\t%h0";
6291       else
6292         {
6293           gcc_assert (operands[2] == constm1_rtx
6294                       || (GET_CODE (operands[2]) == CONST_INT
6295                           && INTVAL (operands[2]) == 255));
6296           return "dec{b}\t%h0";
6297         }
6299     default:
6300       return "add{b}\t{%2, %h0|%h0, %2}";
6301     }
6303   [(set (attr "type")
6304      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6305         (const_string "incdec")
6306         (const_string "alu")))
6307    (set_attr "mode" "QI")])
6309 (define_insn "*addqi_ext_1_rex64"
6310   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6311                          (const_int 8)
6312                          (const_int 8))
6313         (plus:SI
6314           (zero_extract:SI
6315             (match_operand 1 "ext_register_operand" "0")
6316             (const_int 8)
6317             (const_int 8))
6318           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6319    (clobber (reg:CC FLAGS_REG))]
6320   "TARGET_64BIT"
6322   switch (get_attr_type (insn))
6323     {
6324     case TYPE_INCDEC:
6325       if (operands[2] == const1_rtx)
6326         return "inc{b}\t%h0";
6327       else
6328         {
6329           gcc_assert (operands[2] == constm1_rtx
6330                       || (GET_CODE (operands[2]) == CONST_INT
6331                           && INTVAL (operands[2]) == 255));
6332           return "dec{b}\t%h0";
6333         }
6335     default:
6336       return "add{b}\t{%2, %h0|%h0, %2}";
6337     }
6339   [(set (attr "type")
6340      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6341         (const_string "incdec")
6342         (const_string "alu")))
6343    (set_attr "mode" "QI")])
6345 (define_insn "*addqi_ext_2"
6346   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6347                          (const_int 8)
6348                          (const_int 8))
6349         (plus:SI
6350           (zero_extract:SI
6351             (match_operand 1 "ext_register_operand" "%0")
6352             (const_int 8)
6353             (const_int 8))
6354           (zero_extract:SI
6355             (match_operand 2 "ext_register_operand" "Q")
6356             (const_int 8)
6357             (const_int 8))))
6358    (clobber (reg:CC FLAGS_REG))]
6359   ""
6360   "add{b}\t{%h2, %h0|%h0, %h2}"
6361   [(set_attr "type" "alu")
6362    (set_attr "mode" "QI")])
6364 ;; The patterns that match these are at the end of this file.
6366 (define_expand "addxf3"
6367   [(set (match_operand:XF 0 "register_operand" "")
6368         (plus:XF (match_operand:XF 1 "register_operand" "")
6369                  (match_operand:XF 2 "register_operand" "")))]
6370   "TARGET_80387"
6371   "")
6373 (define_expand "adddf3"
6374   [(set (match_operand:DF 0 "register_operand" "")
6375         (plus:DF (match_operand:DF 1 "register_operand" "")
6376                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6377   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6378   "")
6380 (define_expand "addsf3"
6381   [(set (match_operand:SF 0 "register_operand" "")
6382         (plus:SF (match_operand:SF 1 "register_operand" "")
6383                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6384   "TARGET_80387 || TARGET_SSE_MATH"
6385   "")
6387 ;; Subtract instructions
6389 ;; %%% splits for subsidi3
6391 (define_expand "subdi3"
6392   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6393                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6394                              (match_operand:DI 2 "x86_64_general_operand" "")))
6395               (clobber (reg:CC FLAGS_REG))])]
6396   ""
6397   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6399 (define_insn "*subdi3_1"
6400   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6401         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6402                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6403    (clobber (reg:CC FLAGS_REG))]
6404   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6405   "#")
6407 (define_split
6408   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6409         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6410                   (match_operand:DI 2 "general_operand" "")))
6411    (clobber (reg:CC FLAGS_REG))]
6412   "!TARGET_64BIT && reload_completed"
6413   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6414               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6415    (parallel [(set (match_dup 3)
6416                    (minus:SI (match_dup 4)
6417                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6418                                       (match_dup 5))))
6419               (clobber (reg:CC FLAGS_REG))])]
6420   "split_di (operands+0, 1, operands+0, operands+3);
6421    split_di (operands+1, 1, operands+1, operands+4);
6422    split_di (operands+2, 1, operands+2, operands+5);")
6424 (define_insn "subdi3_carry_rex64"
6425   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6426           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6427             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6428                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6429    (clobber (reg:CC FLAGS_REG))]
6430   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6431   "sbb{q}\t{%2, %0|%0, %2}"
6432   [(set_attr "type" "alu")
6433    (set_attr "pent_pair" "pu")
6434    (set_attr "mode" "DI")])
6436 (define_insn "*subdi_1_rex64"
6437   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6438         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6439                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6440    (clobber (reg:CC FLAGS_REG))]
6441   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6442   "sub{q}\t{%2, %0|%0, %2}"
6443   [(set_attr "type" "alu")
6444    (set_attr "mode" "DI")])
6446 (define_insn "*subdi_2_rex64"
6447   [(set (reg FLAGS_REG)
6448         (compare
6449           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6450                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6451           (const_int 0)))
6452    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6453         (minus:DI (match_dup 1) (match_dup 2)))]
6454   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6455    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6456   "sub{q}\t{%2, %0|%0, %2}"
6457   [(set_attr "type" "alu")
6458    (set_attr "mode" "DI")])
6460 (define_insn "*subdi_3_rex63"
6461   [(set (reg FLAGS_REG)
6462         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6463                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6464    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6465         (minus:DI (match_dup 1) (match_dup 2)))]
6466   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6467    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6468   "sub{q}\t{%2, %0|%0, %2}"
6469   [(set_attr "type" "alu")
6470    (set_attr "mode" "DI")])
6472 (define_insn "subqi3_carry"
6473   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6474           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6475             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6476                (match_operand:QI 2 "general_operand" "qi,qm"))))
6477    (clobber (reg:CC FLAGS_REG))]
6478   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6479   "sbb{b}\t{%2, %0|%0, %2}"
6480   [(set_attr "type" "alu")
6481    (set_attr "pent_pair" "pu")
6482    (set_attr "mode" "QI")])
6484 (define_insn "subhi3_carry"
6485   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6486           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6487             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6488                (match_operand:HI 2 "general_operand" "ri,rm"))))
6489    (clobber (reg:CC FLAGS_REG))]
6490   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6491   "sbb{w}\t{%2, %0|%0, %2}"
6492   [(set_attr "type" "alu")
6493    (set_attr "pent_pair" "pu")
6494    (set_attr "mode" "HI")])
6496 (define_insn "subsi3_carry"
6497   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6498           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6499             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6500                (match_operand:SI 2 "general_operand" "ri,rm"))))
6501    (clobber (reg:CC FLAGS_REG))]
6502   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6503   "sbb{l}\t{%2, %0|%0, %2}"
6504   [(set_attr "type" "alu")
6505    (set_attr "pent_pair" "pu")
6506    (set_attr "mode" "SI")])
6508 (define_insn "subsi3_carry_zext"
6509   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6510           (zero_extend:DI
6511             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6512               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6513                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6514    (clobber (reg:CC FLAGS_REG))]
6515   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6516   "sbb{l}\t{%2, %k0|%k0, %2}"
6517   [(set_attr "type" "alu")
6518    (set_attr "pent_pair" "pu")
6519    (set_attr "mode" "SI")])
6521 (define_expand "subsi3"
6522   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6523                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6524                              (match_operand:SI 2 "general_operand" "")))
6525               (clobber (reg:CC FLAGS_REG))])]
6526   ""
6527   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6529 (define_insn "*subsi_1"
6530   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6531         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6532                   (match_operand:SI 2 "general_operand" "ri,rm")))
6533    (clobber (reg:CC FLAGS_REG))]
6534   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6535   "sub{l}\t{%2, %0|%0, %2}"
6536   [(set_attr "type" "alu")
6537    (set_attr "mode" "SI")])
6539 (define_insn "*subsi_1_zext"
6540   [(set (match_operand:DI 0 "register_operand" "=r")
6541         (zero_extend:DI
6542           (minus:SI (match_operand:SI 1 "register_operand" "0")
6543                     (match_operand:SI 2 "general_operand" "rim"))))
6544    (clobber (reg:CC FLAGS_REG))]
6545   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6546   "sub{l}\t{%2, %k0|%k0, %2}"
6547   [(set_attr "type" "alu")
6548    (set_attr "mode" "SI")])
6550 (define_insn "*subsi_2"
6551   [(set (reg FLAGS_REG)
6552         (compare
6553           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6554                     (match_operand:SI 2 "general_operand" "ri,rm"))
6555           (const_int 0)))
6556    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6557         (minus:SI (match_dup 1) (match_dup 2)))]
6558   "ix86_match_ccmode (insn, CCGOCmode)
6559    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6560   "sub{l}\t{%2, %0|%0, %2}"
6561   [(set_attr "type" "alu")
6562    (set_attr "mode" "SI")])
6564 (define_insn "*subsi_2_zext"
6565   [(set (reg FLAGS_REG)
6566         (compare
6567           (minus:SI (match_operand:SI 1 "register_operand" "0")
6568                     (match_operand:SI 2 "general_operand" "rim"))
6569           (const_int 0)))
6570    (set (match_operand:DI 0 "register_operand" "=r")
6571         (zero_extend:DI
6572           (minus:SI (match_dup 1)
6573                     (match_dup 2))))]
6574   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6575    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6576   "sub{l}\t{%2, %k0|%k0, %2}"
6577   [(set_attr "type" "alu")
6578    (set_attr "mode" "SI")])
6580 (define_insn "*subsi_3"
6581   [(set (reg FLAGS_REG)
6582         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6583                  (match_operand:SI 2 "general_operand" "ri,rm")))
6584    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6585         (minus:SI (match_dup 1) (match_dup 2)))]
6586   "ix86_match_ccmode (insn, CCmode)
6587    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6588   "sub{l}\t{%2, %0|%0, %2}"
6589   [(set_attr "type" "alu")
6590    (set_attr "mode" "SI")])
6592 (define_insn "*subsi_3_zext"
6593   [(set (reg FLAGS_REG)
6594         (compare (match_operand:SI 1 "register_operand" "0")
6595                  (match_operand:SI 2 "general_operand" "rim")))
6596    (set (match_operand:DI 0 "register_operand" "=r")
6597         (zero_extend:DI
6598           (minus:SI (match_dup 1)
6599                     (match_dup 2))))]
6600   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6601    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6602   "sub{q}\t{%2, %0|%0, %2}"
6603   [(set_attr "type" "alu")
6604    (set_attr "mode" "DI")])
6606 (define_expand "subhi3"
6607   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6608                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6609                              (match_operand:HI 2 "general_operand" "")))
6610               (clobber (reg:CC FLAGS_REG))])]
6611   "TARGET_HIMODE_MATH"
6612   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6614 (define_insn "*subhi_1"
6615   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6616         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6617                   (match_operand:HI 2 "general_operand" "ri,rm")))
6618    (clobber (reg:CC FLAGS_REG))]
6619   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6620   "sub{w}\t{%2, %0|%0, %2}"
6621   [(set_attr "type" "alu")
6622    (set_attr "mode" "HI")])
6624 (define_insn "*subhi_2"
6625   [(set (reg FLAGS_REG)
6626         (compare
6627           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6628                     (match_operand:HI 2 "general_operand" "ri,rm"))
6629           (const_int 0)))
6630    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6631         (minus:HI (match_dup 1) (match_dup 2)))]
6632   "ix86_match_ccmode (insn, CCGOCmode)
6633    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6634   "sub{w}\t{%2, %0|%0, %2}"
6635   [(set_attr "type" "alu")
6636    (set_attr "mode" "HI")])
6638 (define_insn "*subhi_3"
6639   [(set (reg FLAGS_REG)
6640         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6641                  (match_operand:HI 2 "general_operand" "ri,rm")))
6642    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6643         (minus:HI (match_dup 1) (match_dup 2)))]
6644   "ix86_match_ccmode (insn, CCmode)
6645    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6646   "sub{w}\t{%2, %0|%0, %2}"
6647   [(set_attr "type" "alu")
6648    (set_attr "mode" "HI")])
6650 (define_expand "subqi3"
6651   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6652                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6653                              (match_operand:QI 2 "general_operand" "")))
6654               (clobber (reg:CC FLAGS_REG))])]
6655   "TARGET_QIMODE_MATH"
6656   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6658 (define_insn "*subqi_1"
6659   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6660         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6661                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6662    (clobber (reg:CC FLAGS_REG))]
6663   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6664   "sub{b}\t{%2, %0|%0, %2}"
6665   [(set_attr "type" "alu")
6666    (set_attr "mode" "QI")])
6668 (define_insn "*subqi_1_slp"
6669   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6670         (minus:QI (match_dup 0)
6671                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6672    (clobber (reg:CC FLAGS_REG))]
6673   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6674    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6675   "sub{b}\t{%1, %0|%0, %1}"
6676   [(set_attr "type" "alu1")
6677    (set_attr "mode" "QI")])
6679 (define_insn "*subqi_2"
6680   [(set (reg FLAGS_REG)
6681         (compare
6682           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6683                     (match_operand:QI 2 "general_operand" "qi,qm"))
6684           (const_int 0)))
6685    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6686         (minus:HI (match_dup 1) (match_dup 2)))]
6687   "ix86_match_ccmode (insn, CCGOCmode)
6688    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6689   "sub{b}\t{%2, %0|%0, %2}"
6690   [(set_attr "type" "alu")
6691    (set_attr "mode" "QI")])
6693 (define_insn "*subqi_3"
6694   [(set (reg FLAGS_REG)
6695         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6696                  (match_operand:QI 2 "general_operand" "qi,qm")))
6697    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6698         (minus:HI (match_dup 1) (match_dup 2)))]
6699   "ix86_match_ccmode (insn, CCmode)
6700    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6701   "sub{b}\t{%2, %0|%0, %2}"
6702   [(set_attr "type" "alu")
6703    (set_attr "mode" "QI")])
6705 ;; The patterns that match these are at the end of this file.
6707 (define_expand "subxf3"
6708   [(set (match_operand:XF 0 "register_operand" "")
6709         (minus:XF (match_operand:XF 1 "register_operand" "")
6710                   (match_operand:XF 2 "register_operand" "")))]
6711   "TARGET_80387"
6712   "")
6714 (define_expand "subdf3"
6715   [(set (match_operand:DF 0 "register_operand" "")
6716         (minus:DF (match_operand:DF 1 "register_operand" "")
6717                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6718   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6719   "")
6721 (define_expand "subsf3"
6722   [(set (match_operand:SF 0 "register_operand" "")
6723         (minus:SF (match_operand:SF 1 "register_operand" "")
6724                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6725   "TARGET_80387 || TARGET_SSE_MATH"
6726   "")
6728 ;; Multiply instructions
6730 (define_expand "muldi3"
6731   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6732                    (mult:DI (match_operand:DI 1 "register_operand" "")
6733                             (match_operand:DI 2 "x86_64_general_operand" "")))
6734               (clobber (reg:CC FLAGS_REG))])]
6735   "TARGET_64BIT"
6736   "")
6738 (define_insn "*muldi3_1_rex64"
6739   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6740         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6741                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6742    (clobber (reg:CC FLAGS_REG))]
6743   "TARGET_64BIT
6744    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6745   "@
6746    imul{q}\t{%2, %1, %0|%0, %1, %2}
6747    imul{q}\t{%2, %1, %0|%0, %1, %2}
6748    imul{q}\t{%2, %0|%0, %2}"
6749   [(set_attr "type" "imul")
6750    (set_attr "prefix_0f" "0,0,1")
6751    (set (attr "athlon_decode")
6752         (cond [(eq_attr "cpu" "athlon")
6753                   (const_string "vector")
6754                (eq_attr "alternative" "1")
6755                   (const_string "vector")
6756                (and (eq_attr "alternative" "2")
6757                     (match_operand 1 "memory_operand" ""))
6758                   (const_string "vector")]
6759               (const_string "direct")))
6760    (set_attr "mode" "DI")])
6762 (define_expand "mulsi3"
6763   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6764                    (mult:SI (match_operand:SI 1 "register_operand" "")
6765                             (match_operand:SI 2 "general_operand" "")))
6766               (clobber (reg:CC FLAGS_REG))])]
6767   ""
6768   "")
6770 (define_insn "*mulsi3_1"
6771   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6772         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6773                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6774    (clobber (reg:CC FLAGS_REG))]
6775   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6776   "@
6777    imul{l}\t{%2, %1, %0|%0, %1, %2}
6778    imul{l}\t{%2, %1, %0|%0, %1, %2}
6779    imul{l}\t{%2, %0|%0, %2}"
6780   [(set_attr "type" "imul")
6781    (set_attr "prefix_0f" "0,0,1")
6782    (set (attr "athlon_decode")
6783         (cond [(eq_attr "cpu" "athlon")
6784                   (const_string "vector")
6785                (eq_attr "alternative" "1")
6786                   (const_string "vector")
6787                (and (eq_attr "alternative" "2")
6788                     (match_operand 1 "memory_operand" ""))
6789                   (const_string "vector")]
6790               (const_string "direct")))
6791    (set_attr "mode" "SI")])
6793 (define_insn "*mulsi3_1_zext"
6794   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6795         (zero_extend:DI
6796           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6797                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6798    (clobber (reg:CC FLAGS_REG))]
6799   "TARGET_64BIT
6800    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6801   "@
6802    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6803    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6804    imul{l}\t{%2, %k0|%k0, %2}"
6805   [(set_attr "type" "imul")
6806    (set_attr "prefix_0f" "0,0,1")
6807    (set (attr "athlon_decode")
6808         (cond [(eq_attr "cpu" "athlon")
6809                   (const_string "vector")
6810                (eq_attr "alternative" "1")
6811                   (const_string "vector")
6812                (and (eq_attr "alternative" "2")
6813                     (match_operand 1 "memory_operand" ""))
6814                   (const_string "vector")]
6815               (const_string "direct")))
6816    (set_attr "mode" "SI")])
6818 (define_expand "mulhi3"
6819   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6820                    (mult:HI (match_operand:HI 1 "register_operand" "")
6821                             (match_operand:HI 2 "general_operand" "")))
6822               (clobber (reg:CC FLAGS_REG))])]
6823   "TARGET_HIMODE_MATH"
6824   "")
6826 (define_insn "*mulhi3_1"
6827   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6828         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6829                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6830    (clobber (reg:CC FLAGS_REG))]
6831   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6832   "@
6833    imul{w}\t{%2, %1, %0|%0, %1, %2}
6834    imul{w}\t{%2, %1, %0|%0, %1, %2}
6835    imul{w}\t{%2, %0|%0, %2}"
6836   [(set_attr "type" "imul")
6837    (set_attr "prefix_0f" "0,0,1")
6838    (set (attr "athlon_decode")
6839         (cond [(eq_attr "cpu" "athlon")
6840                   (const_string "vector")
6841                (eq_attr "alternative" "1,2")
6842                   (const_string "vector")]
6843               (const_string "direct")))
6844    (set_attr "mode" "HI")])
6846 (define_expand "mulqi3"
6847   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6848                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6849                             (match_operand:QI 2 "register_operand" "")))
6850               (clobber (reg:CC FLAGS_REG))])]
6851   "TARGET_QIMODE_MATH"
6852   "")
6854 (define_insn "*mulqi3_1"
6855   [(set (match_operand:QI 0 "register_operand" "=a")
6856         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6857                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6858    (clobber (reg:CC FLAGS_REG))]
6859   "TARGET_QIMODE_MATH
6860    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6861   "mul{b}\t%2"
6862   [(set_attr "type" "imul")
6863    (set_attr "length_immediate" "0")
6864    (set (attr "athlon_decode")
6865      (if_then_else (eq_attr "cpu" "athlon")
6866         (const_string "vector")
6867         (const_string "direct")))
6868    (set_attr "mode" "QI")])
6870 (define_expand "umulqihi3"
6871   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6872                    (mult:HI (zero_extend:HI
6873                               (match_operand:QI 1 "nonimmediate_operand" ""))
6874                             (zero_extend:HI
6875                               (match_operand:QI 2 "register_operand" ""))))
6876               (clobber (reg:CC FLAGS_REG))])]
6877   "TARGET_QIMODE_MATH"
6878   "")
6880 (define_insn "*umulqihi3_1"
6881   [(set (match_operand:HI 0 "register_operand" "=a")
6882         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6883                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6884    (clobber (reg:CC FLAGS_REG))]
6885   "TARGET_QIMODE_MATH
6886    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6887   "mul{b}\t%2"
6888   [(set_attr "type" "imul")
6889    (set_attr "length_immediate" "0")
6890    (set (attr "athlon_decode")
6891      (if_then_else (eq_attr "cpu" "athlon")
6892         (const_string "vector")
6893         (const_string "direct")))
6894    (set_attr "mode" "QI")])
6896 (define_expand "mulqihi3"
6897   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6898                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6899                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6900               (clobber (reg:CC FLAGS_REG))])]
6901   "TARGET_QIMODE_MATH"
6902   "")
6904 (define_insn "*mulqihi3_insn"
6905   [(set (match_operand:HI 0 "register_operand" "=a")
6906         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6907                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6908    (clobber (reg:CC FLAGS_REG))]
6909   "TARGET_QIMODE_MATH
6910    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6911   "imul{b}\t%2"
6912   [(set_attr "type" "imul")
6913    (set_attr "length_immediate" "0")
6914    (set (attr "athlon_decode")
6915      (if_then_else (eq_attr "cpu" "athlon")
6916         (const_string "vector")
6917         (const_string "direct")))
6918    (set_attr "mode" "QI")])
6920 (define_expand "umulditi3"
6921   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6922                    (mult:TI (zero_extend:TI
6923                               (match_operand:DI 1 "nonimmediate_operand" ""))
6924                             (zero_extend:TI
6925                               (match_operand:DI 2 "register_operand" ""))))
6926               (clobber (reg:CC FLAGS_REG))])]
6927   "TARGET_64BIT"
6928   "")
6930 (define_insn "*umulditi3_insn"
6931   [(set (match_operand:TI 0 "register_operand" "=A")
6932         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6933                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6934    (clobber (reg:CC FLAGS_REG))]
6935   "TARGET_64BIT
6936    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6937   "mul{q}\t%2"
6938   [(set_attr "type" "imul")
6939    (set_attr "length_immediate" "0")
6940    (set (attr "athlon_decode")
6941      (if_then_else (eq_attr "cpu" "athlon")
6942         (const_string "vector")
6943         (const_string "double")))
6944    (set_attr "mode" "DI")])
6946 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6947 (define_expand "umulsidi3"
6948   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6949                    (mult:DI (zero_extend:DI
6950                               (match_operand:SI 1 "nonimmediate_operand" ""))
6951                             (zero_extend:DI
6952                               (match_operand:SI 2 "register_operand" ""))))
6953               (clobber (reg:CC FLAGS_REG))])]
6954   "!TARGET_64BIT"
6955   "")
6957 (define_insn "*umulsidi3_insn"
6958   [(set (match_operand:DI 0 "register_operand" "=A")
6959         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6960                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6961    (clobber (reg:CC FLAGS_REG))]
6962   "!TARGET_64BIT
6963    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6964   "mul{l}\t%2"
6965   [(set_attr "type" "imul")
6966    (set_attr "length_immediate" "0")
6967    (set (attr "athlon_decode")
6968      (if_then_else (eq_attr "cpu" "athlon")
6969         (const_string "vector")
6970         (const_string "double")))
6971    (set_attr "mode" "SI")])
6973 (define_expand "mulditi3"
6974   [(parallel [(set (match_operand:TI 0 "register_operand" "")
6975                    (mult:TI (sign_extend:TI
6976                               (match_operand:DI 1 "nonimmediate_operand" ""))
6977                             (sign_extend:TI
6978                               (match_operand:DI 2 "register_operand" ""))))
6979               (clobber (reg:CC FLAGS_REG))])]
6980   "TARGET_64BIT"
6981   "")
6983 (define_insn "*mulditi3_insn"
6984   [(set (match_operand:TI 0 "register_operand" "=A")
6985         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6986                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6987    (clobber (reg:CC FLAGS_REG))]
6988   "TARGET_64BIT
6989    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6990   "imul{q}\t%2"
6991   [(set_attr "type" "imul")
6992    (set_attr "length_immediate" "0")
6993    (set (attr "athlon_decode")
6994      (if_then_else (eq_attr "cpu" "athlon")
6995         (const_string "vector")
6996         (const_string "double")))
6997    (set_attr "mode" "DI")])
6999 (define_expand "mulsidi3"
7000   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7001                    (mult:DI (sign_extend:DI
7002                               (match_operand:SI 1 "nonimmediate_operand" ""))
7003                             (sign_extend:DI
7004                               (match_operand:SI 2 "register_operand" ""))))
7005               (clobber (reg:CC FLAGS_REG))])]
7006   "!TARGET_64BIT"
7007   "")
7009 (define_insn "*mulsidi3_insn"
7010   [(set (match_operand:DI 0 "register_operand" "=A")
7011         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7012                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7013    (clobber (reg:CC FLAGS_REG))]
7014   "!TARGET_64BIT
7015    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7016   "imul{l}\t%2"
7017   [(set_attr "type" "imul")
7018    (set_attr "length_immediate" "0")
7019    (set (attr "athlon_decode")
7020      (if_then_else (eq_attr "cpu" "athlon")
7021         (const_string "vector")
7022         (const_string "double")))
7023    (set_attr "mode" "SI")])
7025 (define_expand "umuldi3_highpart"
7026   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7027                    (truncate:DI
7028                      (lshiftrt:TI
7029                        (mult:TI (zero_extend:TI
7030                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7031                                 (zero_extend:TI
7032                                   (match_operand:DI 2 "register_operand" "")))
7033                        (const_int 64))))
7034               (clobber (match_scratch:DI 3 ""))
7035               (clobber (reg:CC FLAGS_REG))])]
7036   "TARGET_64BIT"
7037   "")
7039 (define_insn "*umuldi3_highpart_rex64"
7040   [(set (match_operand:DI 0 "register_operand" "=d")
7041         (truncate:DI
7042           (lshiftrt:TI
7043             (mult:TI (zero_extend:TI
7044                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7045                      (zero_extend:TI
7046                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7047             (const_int 64))))
7048    (clobber (match_scratch:DI 3 "=1"))
7049    (clobber (reg:CC FLAGS_REG))]
7050   "TARGET_64BIT
7051    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7052   "mul{q}\t%2"
7053   [(set_attr "type" "imul")
7054    (set_attr "length_immediate" "0")
7055    (set (attr "athlon_decode")
7056      (if_then_else (eq_attr "cpu" "athlon")
7057         (const_string "vector")
7058         (const_string "double")))
7059    (set_attr "mode" "DI")])
7061 (define_expand "umulsi3_highpart"
7062   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7063                    (truncate:SI
7064                      (lshiftrt:DI
7065                        (mult:DI (zero_extend:DI
7066                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7067                                 (zero_extend:DI
7068                                   (match_operand:SI 2 "register_operand" "")))
7069                        (const_int 32))))
7070               (clobber (match_scratch:SI 3 ""))
7071               (clobber (reg:CC FLAGS_REG))])]
7072   ""
7073   "")
7075 (define_insn "*umulsi3_highpart_insn"
7076   [(set (match_operand:SI 0 "register_operand" "=d")
7077         (truncate:SI
7078           (lshiftrt:DI
7079             (mult:DI (zero_extend:DI
7080                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7081                      (zero_extend:DI
7082                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7083             (const_int 32))))
7084    (clobber (match_scratch:SI 3 "=1"))
7085    (clobber (reg:CC FLAGS_REG))]
7086   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7087   "mul{l}\t%2"
7088   [(set_attr "type" "imul")
7089    (set_attr "length_immediate" "0")
7090    (set (attr "athlon_decode")
7091      (if_then_else (eq_attr "cpu" "athlon")
7092         (const_string "vector")
7093         (const_string "double")))
7094    (set_attr "mode" "SI")])
7096 (define_insn "*umulsi3_highpart_zext"
7097   [(set (match_operand:DI 0 "register_operand" "=d")
7098         (zero_extend:DI (truncate:SI
7099           (lshiftrt:DI
7100             (mult:DI (zero_extend:DI
7101                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7102                      (zero_extend:DI
7103                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7104             (const_int 32)))))
7105    (clobber (match_scratch:SI 3 "=1"))
7106    (clobber (reg:CC FLAGS_REG))]
7107   "TARGET_64BIT
7108    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7109   "mul{l}\t%2"
7110   [(set_attr "type" "imul")
7111    (set_attr "length_immediate" "0")
7112    (set (attr "athlon_decode")
7113      (if_then_else (eq_attr "cpu" "athlon")
7114         (const_string "vector")
7115         (const_string "double")))
7116    (set_attr "mode" "SI")])
7118 (define_expand "smuldi3_highpart"
7119   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7120                    (truncate:DI
7121                      (lshiftrt:TI
7122                        (mult:TI (sign_extend:TI
7123                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7124                                 (sign_extend:TI
7125                                   (match_operand:DI 2 "register_operand" "")))
7126                        (const_int 64))))
7127               (clobber (match_scratch:DI 3 ""))
7128               (clobber (reg:CC FLAGS_REG))])]
7129   "TARGET_64BIT"
7130   "")
7132 (define_insn "*smuldi3_highpart_rex64"
7133   [(set (match_operand:DI 0 "register_operand" "=d")
7134         (truncate:DI
7135           (lshiftrt:TI
7136             (mult:TI (sign_extend:TI
7137                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7138                      (sign_extend:TI
7139                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7140             (const_int 64))))
7141    (clobber (match_scratch:DI 3 "=1"))
7142    (clobber (reg:CC FLAGS_REG))]
7143   "TARGET_64BIT
7144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7145   "imul{q}\t%2"
7146   [(set_attr "type" "imul")
7147    (set (attr "athlon_decode")
7148      (if_then_else (eq_attr "cpu" "athlon")
7149         (const_string "vector")
7150         (const_string "double")))
7151    (set_attr "mode" "DI")])
7153 (define_expand "smulsi3_highpart"
7154   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7155                    (truncate:SI
7156                      (lshiftrt:DI
7157                        (mult:DI (sign_extend:DI
7158                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7159                                 (sign_extend:DI
7160                                   (match_operand:SI 2 "register_operand" "")))
7161                        (const_int 32))))
7162               (clobber (match_scratch:SI 3 ""))
7163               (clobber (reg:CC FLAGS_REG))])]
7164   ""
7165   "")
7167 (define_insn "*smulsi3_highpart_insn"
7168   [(set (match_operand:SI 0 "register_operand" "=d")
7169         (truncate:SI
7170           (lshiftrt:DI
7171             (mult:DI (sign_extend:DI
7172                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7173                      (sign_extend:DI
7174                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7175             (const_int 32))))
7176    (clobber (match_scratch:SI 3 "=1"))
7177    (clobber (reg:CC FLAGS_REG))]
7178   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7179   "imul{l}\t%2"
7180   [(set_attr "type" "imul")
7181    (set (attr "athlon_decode")
7182      (if_then_else (eq_attr "cpu" "athlon")
7183         (const_string "vector")
7184         (const_string "double")))
7185    (set_attr "mode" "SI")])
7187 (define_insn "*smulsi3_highpart_zext"
7188   [(set (match_operand:DI 0 "register_operand" "=d")
7189         (zero_extend:DI (truncate:SI
7190           (lshiftrt:DI
7191             (mult:DI (sign_extend:DI
7192                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7193                      (sign_extend:DI
7194                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7195             (const_int 32)))))
7196    (clobber (match_scratch:SI 3 "=1"))
7197    (clobber (reg:CC FLAGS_REG))]
7198   "TARGET_64BIT
7199    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7200   "imul{l}\t%2"
7201   [(set_attr "type" "imul")
7202    (set (attr "athlon_decode")
7203      (if_then_else (eq_attr "cpu" "athlon")
7204         (const_string "vector")
7205         (const_string "double")))
7206    (set_attr "mode" "SI")])
7208 ;; The patterns that match these are at the end of this file.
7210 (define_expand "mulxf3"
7211   [(set (match_operand:XF 0 "register_operand" "")
7212         (mult:XF (match_operand:XF 1 "register_operand" "")
7213                  (match_operand:XF 2 "register_operand" "")))]
7214   "TARGET_80387"
7215   "")
7217 (define_expand "muldf3"
7218   [(set (match_operand:DF 0 "register_operand" "")
7219         (mult:DF (match_operand:DF 1 "register_operand" "")
7220                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7221   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7222   "")
7224 (define_expand "mulsf3"
7225   [(set (match_operand:SF 0 "register_operand" "")
7226         (mult:SF (match_operand:SF 1 "register_operand" "")
7227                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7228   "TARGET_80387 || TARGET_SSE_MATH"
7229   "")
7231 ;; Divide instructions
7233 (define_insn "divqi3"
7234   [(set (match_operand:QI 0 "register_operand" "=a")
7235         (div:QI (match_operand:HI 1 "register_operand" "0")
7236                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7237    (clobber (reg:CC FLAGS_REG))]
7238   "TARGET_QIMODE_MATH"
7239   "idiv{b}\t%2"
7240   [(set_attr "type" "idiv")
7241    (set_attr "mode" "QI")])
7243 (define_insn "udivqi3"
7244   [(set (match_operand:QI 0 "register_operand" "=a")
7245         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7246                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7247    (clobber (reg:CC FLAGS_REG))]
7248   "TARGET_QIMODE_MATH"
7249   "div{b}\t%2"
7250   [(set_attr "type" "idiv")
7251    (set_attr "mode" "QI")])
7253 ;; The patterns that match these are at the end of this file.
7255 (define_expand "divxf3"
7256   [(set (match_operand:XF 0 "register_operand" "")
7257         (div:XF (match_operand:XF 1 "register_operand" "")
7258                 (match_operand:XF 2 "register_operand" "")))]
7259   "TARGET_80387"
7260   "")
7262 (define_expand "divdf3"
7263   [(set (match_operand:DF 0 "register_operand" "")
7264         (div:DF (match_operand:DF 1 "register_operand" "")
7265                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7266    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7267    "")
7269 (define_expand "divsf3"
7270   [(set (match_operand:SF 0 "register_operand" "")
7271         (div:SF (match_operand:SF 1 "register_operand" "")
7272                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7273   "TARGET_80387 || TARGET_SSE_MATH"
7274   "")
7276 ;; Remainder instructions.
7278 (define_expand "divmoddi4"
7279   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7280                    (div:DI (match_operand:DI 1 "register_operand" "")
7281                            (match_operand:DI 2 "nonimmediate_operand" "")))
7282               (set (match_operand:DI 3 "register_operand" "")
7283                    (mod:DI (match_dup 1) (match_dup 2)))
7284               (clobber (reg:CC FLAGS_REG))])]
7285   "TARGET_64BIT"
7286   "")
7288 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7289 ;; Penalize eax case slightly because it results in worse scheduling
7290 ;; of code.
7291 (define_insn "*divmoddi4_nocltd_rex64"
7292   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7293         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7294                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7295    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7296         (mod:DI (match_dup 2) (match_dup 3)))
7297    (clobber (reg:CC FLAGS_REG))]
7298   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7299   "#"
7300   [(set_attr "type" "multi")])
7302 (define_insn "*divmoddi4_cltd_rex64"
7303   [(set (match_operand:DI 0 "register_operand" "=a")
7304         (div:DI (match_operand:DI 2 "register_operand" "a")
7305                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7306    (set (match_operand:DI 1 "register_operand" "=&d")
7307         (mod:DI (match_dup 2) (match_dup 3)))
7308    (clobber (reg:CC FLAGS_REG))]
7309   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7310   "#"
7311   [(set_attr "type" "multi")])
7313 (define_insn "*divmoddi_noext_rex64"
7314   [(set (match_operand:DI 0 "register_operand" "=a")
7315         (div:DI (match_operand:DI 1 "register_operand" "0")
7316                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7317    (set (match_operand:DI 3 "register_operand" "=d")
7318         (mod:DI (match_dup 1) (match_dup 2)))
7319    (use (match_operand:DI 4 "register_operand" "3"))
7320    (clobber (reg:CC FLAGS_REG))]
7321   "TARGET_64BIT"
7322   "idiv{q}\t%2"
7323   [(set_attr "type" "idiv")
7324    (set_attr "mode" "DI")])
7326 (define_split
7327   [(set (match_operand:DI 0 "register_operand" "")
7328         (div:DI (match_operand:DI 1 "register_operand" "")
7329                 (match_operand:DI 2 "nonimmediate_operand" "")))
7330    (set (match_operand:DI 3 "register_operand" "")
7331         (mod:DI (match_dup 1) (match_dup 2)))
7332    (clobber (reg:CC FLAGS_REG))]
7333   "TARGET_64BIT && reload_completed"
7334   [(parallel [(set (match_dup 3)
7335                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7336               (clobber (reg:CC FLAGS_REG))])
7337    (parallel [(set (match_dup 0)
7338                    (div:DI (reg:DI 0) (match_dup 2)))
7339               (set (match_dup 3)
7340                    (mod:DI (reg:DI 0) (match_dup 2)))
7341               (use (match_dup 3))
7342               (clobber (reg:CC FLAGS_REG))])]
7344   /* Avoid use of cltd in favor of a mov+shift.  */
7345   if (!TARGET_USE_CLTD && !optimize_size)
7346     {
7347       if (true_regnum (operands[1]))
7348         emit_move_insn (operands[0], operands[1]);
7349       else
7350         emit_move_insn (operands[3], operands[1]);
7351       operands[4] = operands[3];
7352     }
7353   else
7354     {
7355       gcc_assert (!true_regnum (operands[1]));
7356       operands[4] = operands[1];
7357     }
7361 (define_expand "divmodsi4"
7362   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7363                    (div:SI (match_operand:SI 1 "register_operand" "")
7364                            (match_operand:SI 2 "nonimmediate_operand" "")))
7365               (set (match_operand:SI 3 "register_operand" "")
7366                    (mod:SI (match_dup 1) (match_dup 2)))
7367               (clobber (reg:CC FLAGS_REG))])]
7368   ""
7369   "")
7371 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7372 ;; Penalize eax case slightly because it results in worse scheduling
7373 ;; of code.
7374 (define_insn "*divmodsi4_nocltd"
7375   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7376         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7377                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7378    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7379         (mod:SI (match_dup 2) (match_dup 3)))
7380    (clobber (reg:CC FLAGS_REG))]
7381   "!optimize_size && !TARGET_USE_CLTD"
7382   "#"
7383   [(set_attr "type" "multi")])
7385 (define_insn "*divmodsi4_cltd"
7386   [(set (match_operand:SI 0 "register_operand" "=a")
7387         (div:SI (match_operand:SI 2 "register_operand" "a")
7388                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7389    (set (match_operand:SI 1 "register_operand" "=&d")
7390         (mod:SI (match_dup 2) (match_dup 3)))
7391    (clobber (reg:CC FLAGS_REG))]
7392   "optimize_size || TARGET_USE_CLTD"
7393   "#"
7394   [(set_attr "type" "multi")])
7396 (define_insn "*divmodsi_noext"
7397   [(set (match_operand:SI 0 "register_operand" "=a")
7398         (div:SI (match_operand:SI 1 "register_operand" "0")
7399                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7400    (set (match_operand:SI 3 "register_operand" "=d")
7401         (mod:SI (match_dup 1) (match_dup 2)))
7402    (use (match_operand:SI 4 "register_operand" "3"))
7403    (clobber (reg:CC FLAGS_REG))]
7404   ""
7405   "idiv{l}\t%2"
7406   [(set_attr "type" "idiv")
7407    (set_attr "mode" "SI")])
7409 (define_split
7410   [(set (match_operand:SI 0 "register_operand" "")
7411         (div:SI (match_operand:SI 1 "register_operand" "")
7412                 (match_operand:SI 2 "nonimmediate_operand" "")))
7413    (set (match_operand:SI 3 "register_operand" "")
7414         (mod:SI (match_dup 1) (match_dup 2)))
7415    (clobber (reg:CC FLAGS_REG))]
7416   "reload_completed"
7417   [(parallel [(set (match_dup 3)
7418                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7419               (clobber (reg:CC FLAGS_REG))])
7420    (parallel [(set (match_dup 0)
7421                    (div:SI (reg:SI 0) (match_dup 2)))
7422               (set (match_dup 3)
7423                    (mod:SI (reg:SI 0) (match_dup 2)))
7424               (use (match_dup 3))
7425               (clobber (reg:CC FLAGS_REG))])]
7427   /* Avoid use of cltd in favor of a mov+shift.  */
7428   if (!TARGET_USE_CLTD && !optimize_size)
7429     {
7430       if (true_regnum (operands[1]))
7431         emit_move_insn (operands[0], operands[1]);
7432       else
7433         emit_move_insn (operands[3], operands[1]);
7434       operands[4] = operands[3];
7435     }
7436   else
7437     {
7438       gcc_assert (!true_regnum (operands[1]));
7439       operands[4] = operands[1];
7440     }
7442 ;; %%% Split me.
7443 (define_insn "divmodhi4"
7444   [(set (match_operand:HI 0 "register_operand" "=a")
7445         (div:HI (match_operand:HI 1 "register_operand" "0")
7446                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7447    (set (match_operand:HI 3 "register_operand" "=&d")
7448         (mod:HI (match_dup 1) (match_dup 2)))
7449    (clobber (reg:CC FLAGS_REG))]
7450   "TARGET_HIMODE_MATH"
7451   "cwtd\;idiv{w}\t%2"
7452   [(set_attr "type" "multi")
7453    (set_attr "length_immediate" "0")
7454    (set_attr "mode" "SI")])
7456 (define_insn "udivmoddi4"
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    (clobber (reg:CC FLAGS_REG))]
7463   "TARGET_64BIT"
7464   "xor{q}\t%3, %3\;div{q}\t%2"
7465   [(set_attr "type" "multi")
7466    (set_attr "length_immediate" "0")
7467    (set_attr "mode" "DI")])
7469 (define_insn "*udivmoddi4_noext"
7470   [(set (match_operand:DI 0 "register_operand" "=a")
7471         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7472                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7473    (set (match_operand:DI 3 "register_operand" "=d")
7474         (umod:DI (match_dup 1) (match_dup 2)))
7475    (use (match_dup 3))
7476    (clobber (reg:CC FLAGS_REG))]
7477   "TARGET_64BIT"
7478   "div{q}\t%2"
7479   [(set_attr "type" "idiv")
7480    (set_attr "mode" "DI")])
7482 (define_split
7483   [(set (match_operand:DI 0 "register_operand" "")
7484         (udiv:DI (match_operand:DI 1 "register_operand" "")
7485                  (match_operand:DI 2 "nonimmediate_operand" "")))
7486    (set (match_operand:DI 3 "register_operand" "")
7487         (umod:DI (match_dup 1) (match_dup 2)))
7488    (clobber (reg:CC FLAGS_REG))]
7489   "TARGET_64BIT && reload_completed"
7490   [(set (match_dup 3) (const_int 0))
7491    (parallel [(set (match_dup 0)
7492                    (udiv:DI (match_dup 1) (match_dup 2)))
7493               (set (match_dup 3)
7494                    (umod:DI (match_dup 1) (match_dup 2)))
7495               (use (match_dup 3))
7496               (clobber (reg:CC FLAGS_REG))])]
7497   "")
7499 (define_insn "udivmodsi4"
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    (clobber (reg:CC FLAGS_REG))]
7506   ""
7507   "xor{l}\t%3, %3\;div{l}\t%2"
7508   [(set_attr "type" "multi")
7509    (set_attr "length_immediate" "0")
7510    (set_attr "mode" "SI")])
7512 (define_insn "*udivmodsi4_noext"
7513   [(set (match_operand:SI 0 "register_operand" "=a")
7514         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7515                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7516    (set (match_operand:SI 3 "register_operand" "=d")
7517         (umod:SI (match_dup 1) (match_dup 2)))
7518    (use (match_dup 3))
7519    (clobber (reg:CC FLAGS_REG))]
7520   ""
7521   "div{l}\t%2"
7522   [(set_attr "type" "idiv")
7523    (set_attr "mode" "SI")])
7525 (define_split
7526   [(set (match_operand:SI 0 "register_operand" "")
7527         (udiv:SI (match_operand:SI 1 "register_operand" "")
7528                  (match_operand:SI 2 "nonimmediate_operand" "")))
7529    (set (match_operand:SI 3 "register_operand" "")
7530         (umod:SI (match_dup 1) (match_dup 2)))
7531    (clobber (reg:CC FLAGS_REG))]
7532   "reload_completed"
7533   [(set (match_dup 3) (const_int 0))
7534    (parallel [(set (match_dup 0)
7535                    (udiv:SI (match_dup 1) (match_dup 2)))
7536               (set (match_dup 3)
7537                    (umod:SI (match_dup 1) (match_dup 2)))
7538               (use (match_dup 3))
7539               (clobber (reg:CC FLAGS_REG))])]
7540   "")
7542 (define_expand "udivmodhi4"
7543   [(set (match_dup 4) (const_int 0))
7544    (parallel [(set (match_operand:HI 0 "register_operand" "")
7545                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7546                             (match_operand:HI 2 "nonimmediate_operand" "")))
7547               (set (match_operand:HI 3 "register_operand" "")
7548                    (umod:HI (match_dup 1) (match_dup 2)))
7549               (use (match_dup 4))
7550               (clobber (reg:CC FLAGS_REG))])]
7551   "TARGET_HIMODE_MATH"
7552   "operands[4] = gen_reg_rtx (HImode);")
7554 (define_insn "*udivmodhi_noext"
7555   [(set (match_operand:HI 0 "register_operand" "=a")
7556         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7557                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7558    (set (match_operand:HI 3 "register_operand" "=d")
7559         (umod:HI (match_dup 1) (match_dup 2)))
7560    (use (match_operand:HI 4 "register_operand" "3"))
7561    (clobber (reg:CC FLAGS_REG))]
7562   ""
7563   "div{w}\t%2"
7564   [(set_attr "type" "idiv")
7565    (set_attr "mode" "HI")])
7567 ;; We cannot use div/idiv for double division, because it causes
7568 ;; "division by zero" on the overflow and that's not what we expect
7569 ;; from truncate.  Because true (non truncating) double division is
7570 ;; never generated, we can't create this insn anyway.
7572 ;(define_insn ""
7573 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7574 ;       (truncate:SI
7575 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7576 ;                  (zero_extend:DI
7577 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7578 ;   (set (match_operand:SI 3 "register_operand" "=d")
7579 ;       (truncate:SI
7580 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7581 ;   (clobber (reg:CC FLAGS_REG))]
7582 ;  ""
7583 ;  "div{l}\t{%2, %0|%0, %2}"
7584 ;  [(set_attr "type" "idiv")])
7586 ;;- Logical AND instructions
7588 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7589 ;; Note that this excludes ah.
7591 (define_insn "*testdi_1_rex64"
7592   [(set (reg FLAGS_REG)
7593         (compare
7594           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7595                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7596           (const_int 0)))]
7597   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7598    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7599   "@
7600    test{l}\t{%k1, %k0|%k0, %k1}
7601    test{l}\t{%k1, %k0|%k0, %k1}
7602    test{q}\t{%1, %0|%0, %1}
7603    test{q}\t{%1, %0|%0, %1}
7604    test{q}\t{%1, %0|%0, %1}"
7605   [(set_attr "type" "test")
7606    (set_attr "modrm" "0,1,0,1,1")
7607    (set_attr "mode" "SI,SI,DI,DI,DI")
7608    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7610 (define_insn "testsi_1"
7611   [(set (reg FLAGS_REG)
7612         (compare
7613           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7614                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7615           (const_int 0)))]
7616   "ix86_match_ccmode (insn, CCNOmode)
7617    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7618   "test{l}\t{%1, %0|%0, %1}"
7619   [(set_attr "type" "test")
7620    (set_attr "modrm" "0,1,1")
7621    (set_attr "mode" "SI")
7622    (set_attr "pent_pair" "uv,np,uv")])
7624 (define_expand "testsi_ccno_1"
7625   [(set (reg:CCNO FLAGS_REG)
7626         (compare:CCNO
7627           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7628                   (match_operand:SI 1 "nonmemory_operand" ""))
7629           (const_int 0)))]
7630   ""
7631   "")
7633 (define_insn "*testhi_1"
7634   [(set (reg FLAGS_REG)
7635         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7636                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7637                  (const_int 0)))]
7638   "ix86_match_ccmode (insn, CCNOmode)
7639    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7640   "test{w}\t{%1, %0|%0, %1}"
7641   [(set_attr "type" "test")
7642    (set_attr "modrm" "0,1,1")
7643    (set_attr "mode" "HI")
7644    (set_attr "pent_pair" "uv,np,uv")])
7646 (define_expand "testqi_ccz_1"
7647   [(set (reg:CCZ FLAGS_REG)
7648         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7649                              (match_operand:QI 1 "nonmemory_operand" ""))
7650                  (const_int 0)))]
7651   ""
7652   "")
7654 (define_insn "*testqi_1_maybe_si"
7655   [(set (reg FLAGS_REG)
7656         (compare
7657           (and:QI
7658             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7659             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7660           (const_int 0)))]
7661    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7662     && ix86_match_ccmode (insn,
7663                          GET_CODE (operands[1]) == CONST_INT
7664                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7666   if (which_alternative == 3)
7667     {
7668       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7669         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7670       return "test{l}\t{%1, %k0|%k0, %1}";
7671     }
7672   return "test{b}\t{%1, %0|%0, %1}";
7674   [(set_attr "type" "test")
7675    (set_attr "modrm" "0,1,1,1")
7676    (set_attr "mode" "QI,QI,QI,SI")
7677    (set_attr "pent_pair" "uv,np,uv,np")])
7679 (define_insn "*testqi_1"
7680   [(set (reg FLAGS_REG)
7681         (compare
7682           (and:QI
7683             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7684             (match_operand:QI 1 "general_operand" "n,n,qn"))
7685           (const_int 0)))]
7686   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7687    && ix86_match_ccmode (insn, CCNOmode)"
7688   "test{b}\t{%1, %0|%0, %1}"
7689   [(set_attr "type" "test")
7690    (set_attr "modrm" "0,1,1")
7691    (set_attr "mode" "QI")
7692    (set_attr "pent_pair" "uv,np,uv")])
7694 (define_expand "testqi_ext_ccno_0"
7695   [(set (reg:CCNO FLAGS_REG)
7696         (compare:CCNO
7697           (and:SI
7698             (zero_extract:SI
7699               (match_operand 0 "ext_register_operand" "")
7700               (const_int 8)
7701               (const_int 8))
7702             (match_operand 1 "const_int_operand" ""))
7703           (const_int 0)))]
7704   ""
7705   "")
7707 (define_insn "*testqi_ext_0"
7708   [(set (reg FLAGS_REG)
7709         (compare
7710           (and:SI
7711             (zero_extract:SI
7712               (match_operand 0 "ext_register_operand" "Q")
7713               (const_int 8)
7714               (const_int 8))
7715             (match_operand 1 "const_int_operand" "n"))
7716           (const_int 0)))]
7717   "ix86_match_ccmode (insn, CCNOmode)"
7718   "test{b}\t{%1, %h0|%h0, %1}"
7719   [(set_attr "type" "test")
7720    (set_attr "mode" "QI")
7721    (set_attr "length_immediate" "1")
7722    (set_attr "pent_pair" "np")])
7724 (define_insn "*testqi_ext_1"
7725   [(set (reg FLAGS_REG)
7726         (compare
7727           (and:SI
7728             (zero_extract:SI
7729               (match_operand 0 "ext_register_operand" "Q")
7730               (const_int 8)
7731               (const_int 8))
7732             (zero_extend:SI
7733               (match_operand:QI 1 "general_operand" "Qm")))
7734           (const_int 0)))]
7735   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7736    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7737   "test{b}\t{%1, %h0|%h0, %1}"
7738   [(set_attr "type" "test")
7739    (set_attr "mode" "QI")])
7741 (define_insn "*testqi_ext_1_rex64"
7742   [(set (reg FLAGS_REG)
7743         (compare
7744           (and:SI
7745             (zero_extract:SI
7746               (match_operand 0 "ext_register_operand" "Q")
7747               (const_int 8)
7748               (const_int 8))
7749             (zero_extend:SI
7750               (match_operand:QI 1 "register_operand" "Q")))
7751           (const_int 0)))]
7752   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7753   "test{b}\t{%1, %h0|%h0, %1}"
7754   [(set_attr "type" "test")
7755    (set_attr "mode" "QI")])
7757 (define_insn "*testqi_ext_2"
7758   [(set (reg FLAGS_REG)
7759         (compare
7760           (and:SI
7761             (zero_extract:SI
7762               (match_operand 0 "ext_register_operand" "Q")
7763               (const_int 8)
7764               (const_int 8))
7765             (zero_extract:SI
7766               (match_operand 1 "ext_register_operand" "Q")
7767               (const_int 8)
7768               (const_int 8)))
7769           (const_int 0)))]
7770   "ix86_match_ccmode (insn, CCNOmode)"
7771   "test{b}\t{%h1, %h0|%h0, %h1}"
7772   [(set_attr "type" "test")
7773    (set_attr "mode" "QI")])
7775 ;; Combine likes to form bit extractions for some tests.  Humor it.
7776 (define_insn "*testqi_ext_3"
7777   [(set (reg FLAGS_REG)
7778         (compare (zero_extract:SI
7779                    (match_operand 0 "nonimmediate_operand" "rm")
7780                    (match_operand:SI 1 "const_int_operand" "")
7781                    (match_operand:SI 2 "const_int_operand" ""))
7782                  (const_int 0)))]
7783   "ix86_match_ccmode (insn, CCNOmode)
7784    && (GET_MODE (operands[0]) == SImode
7785        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7786        || GET_MODE (operands[0]) == HImode
7787        || GET_MODE (operands[0]) == QImode)"
7788   "#")
7790 (define_insn "*testqi_ext_3_rex64"
7791   [(set (reg FLAGS_REG)
7792         (compare (zero_extract:DI
7793                    (match_operand 0 "nonimmediate_operand" "rm")
7794                    (match_operand:DI 1 "const_int_operand" "")
7795                    (match_operand:DI 2 "const_int_operand" ""))
7796                  (const_int 0)))]
7797   "TARGET_64BIT
7798    && ix86_match_ccmode (insn, CCNOmode)
7799    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
7800    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7801    /* Ensure that resulting mask is zero or sign extended operand.  */
7802    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7803        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7804            && INTVAL (operands[1]) > 32))
7805    && (GET_MODE (operands[0]) == SImode
7806        || GET_MODE (operands[0]) == DImode
7807        || GET_MODE (operands[0]) == HImode
7808        || GET_MODE (operands[0]) == QImode)"
7809   "#")
7811 (define_split
7812   [(set (match_operand 0 "flags_reg_operand" "")
7813         (match_operator 1 "compare_operator"
7814           [(zero_extract
7815              (match_operand 2 "nonimmediate_operand" "")
7816              (match_operand 3 "const_int_operand" "")
7817              (match_operand 4 "const_int_operand" ""))
7818            (const_int 0)]))]
7819   "ix86_match_ccmode (insn, CCNOmode)"
7820   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7822   rtx val = operands[2];
7823   HOST_WIDE_INT len = INTVAL (operands[3]);
7824   HOST_WIDE_INT pos = INTVAL (operands[4]);
7825   HOST_WIDE_INT mask;
7826   enum machine_mode mode, submode;
7828   mode = GET_MODE (val);
7829   if (GET_CODE (val) == MEM)
7830     {
7831       /* ??? Combine likes to put non-volatile mem extractions in QImode
7832          no matter the size of the test.  So find a mode that works.  */
7833       if (! MEM_VOLATILE_P (val))
7834         {
7835           mode = smallest_mode_for_size (pos + len, MODE_INT);
7836           val = adjust_address (val, mode, 0);
7837         }
7838     }
7839   else if (GET_CODE (val) == SUBREG
7840            && (submode = GET_MODE (SUBREG_REG (val)),
7841                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7842            && pos + len <= GET_MODE_BITSIZE (submode))
7843     {
7844       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7845       mode = submode;
7846       val = SUBREG_REG (val);
7847     }
7848   else if (mode == HImode && pos + len <= 8)
7849     {
7850       /* Small HImode tests can be converted to QImode.  */
7851       mode = QImode;
7852       val = gen_lowpart (QImode, val);
7853     }
7855   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7856   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7858   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7861 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7862 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7863 ;; this is relatively important trick.
7864 ;; Do the conversion only post-reload to avoid limiting of the register class
7865 ;; to QI regs.
7866 (define_split
7867   [(set (match_operand 0 "flags_reg_operand" "")
7868         (match_operator 1 "compare_operator"
7869           [(and (match_operand 2 "register_operand" "")
7870                 (match_operand 3 "const_int_operand" ""))
7871            (const_int 0)]))]
7872    "reload_completed
7873     && QI_REG_P (operands[2])
7874     && GET_MODE (operands[2]) != QImode
7875     && ((ix86_match_ccmode (insn, CCZmode)
7876          && !(INTVAL (operands[3]) & ~(255 << 8)))
7877         || (ix86_match_ccmode (insn, CCNOmode)
7878             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7879   [(set (match_dup 0)
7880         (match_op_dup 1
7881           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7882                    (match_dup 3))
7883            (const_int 0)]))]
7884   "operands[2] = gen_lowpart (SImode, operands[2]);
7885    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7887 (define_split
7888   [(set (match_operand 0 "flags_reg_operand" "")
7889         (match_operator 1 "compare_operator"
7890           [(and (match_operand 2 "nonimmediate_operand" "")
7891                 (match_operand 3 "const_int_operand" ""))
7892            (const_int 0)]))]
7893    "reload_completed
7894     && GET_MODE (operands[2]) != QImode
7895     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7896     && ((ix86_match_ccmode (insn, CCZmode)
7897          && !(INTVAL (operands[3]) & ~255))
7898         || (ix86_match_ccmode (insn, CCNOmode)
7899             && !(INTVAL (operands[3]) & ~127)))"
7900   [(set (match_dup 0)
7901         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7902                          (const_int 0)]))]
7903   "operands[2] = gen_lowpart (QImode, operands[2]);
7904    operands[3] = gen_lowpart (QImode, operands[3]);")
7907 ;; %%% This used to optimize known byte-wide and operations to memory,
7908 ;; and sometimes to QImode registers.  If this is considered useful,
7909 ;; it should be done with splitters.
7911 (define_expand "anddi3"
7912   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7913         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7914                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7915    (clobber (reg:CC FLAGS_REG))]
7916   "TARGET_64BIT"
7917   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7919 (define_insn "*anddi_1_rex64"
7920   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7921         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7922                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7923    (clobber (reg:CC FLAGS_REG))]
7924   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7926   switch (get_attr_type (insn))
7927     {
7928     case TYPE_IMOVX:
7929       {
7930         enum machine_mode mode;
7932         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
7933         if (INTVAL (operands[2]) == 0xff)
7934           mode = QImode;
7935         else
7936           {
7937             gcc_assert (INTVAL (operands[2]) == 0xffff);
7938             mode = HImode;
7939           }
7940         
7941         operands[1] = gen_lowpart (mode, operands[1]);
7942         if (mode == QImode)
7943           return "movz{bq|x}\t{%1,%0|%0, %1}";
7944         else
7945           return "movz{wq|x}\t{%1,%0|%0, %1}";
7946       }
7948     default:
7949       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7950       if (get_attr_mode (insn) == MODE_SI)
7951         return "and{l}\t{%k2, %k0|%k0, %k2}";
7952       else
7953         return "and{q}\t{%2, %0|%0, %2}";
7954     }
7956   [(set_attr "type" "alu,alu,alu,imovx")
7957    (set_attr "length_immediate" "*,*,*,0")
7958    (set_attr "mode" "SI,DI,DI,DI")])
7960 (define_insn "*anddi_2"
7961   [(set (reg FLAGS_REG)
7962         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7963                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7964                  (const_int 0)))
7965    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7966         (and:DI (match_dup 1) (match_dup 2)))]
7967   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7968    && ix86_binary_operator_ok (AND, DImode, operands)"
7969   "@
7970    and{l}\t{%k2, %k0|%k0, %k2}
7971    and{q}\t{%2, %0|%0, %2}
7972    and{q}\t{%2, %0|%0, %2}"
7973   [(set_attr "type" "alu")
7974    (set_attr "mode" "SI,DI,DI")])
7976 (define_expand "andsi3"
7977   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7978         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7979                 (match_operand:SI 2 "general_operand" "")))
7980    (clobber (reg:CC FLAGS_REG))]
7981   ""
7982   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7984 (define_insn "*andsi_1"
7985   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7986         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7987                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7988    (clobber (reg:CC FLAGS_REG))]
7989   "ix86_binary_operator_ok (AND, SImode, operands)"
7991   switch (get_attr_type (insn))
7992     {
7993     case TYPE_IMOVX:
7994       {
7995         enum machine_mode mode;
7997         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
7998         if (INTVAL (operands[2]) == 0xff)
7999           mode = QImode;
8000         else
8001           {
8002             gcc_assert (INTVAL (operands[2]) == 0xffff);
8003             mode = HImode;
8004           }
8005         
8006         operands[1] = gen_lowpart (mode, operands[1]);
8007         if (mode == QImode)
8008           return "movz{bl|x}\t{%1,%0|%0, %1}";
8009         else
8010           return "movz{wl|x}\t{%1,%0|%0, %1}";
8011       }
8013     default:
8014       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8015       return "and{l}\t{%2, %0|%0, %2}";
8016     }
8018   [(set_attr "type" "alu,alu,imovx")
8019    (set_attr "length_immediate" "*,*,0")
8020    (set_attr "mode" "SI")])
8022 (define_split
8023   [(set (match_operand 0 "register_operand" "")
8024         (and (match_dup 0)
8025              (const_int -65536)))
8026    (clobber (reg:CC FLAGS_REG))]
8027   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8028   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8029   "operands[1] = gen_lowpart (HImode, operands[0]);")
8031 (define_split
8032   [(set (match_operand 0 "ext_register_operand" "")
8033         (and (match_dup 0)
8034              (const_int -256)))
8035    (clobber (reg:CC FLAGS_REG))]
8036   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8037   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8038   "operands[1] = gen_lowpart (QImode, operands[0]);")
8040 (define_split
8041   [(set (match_operand 0 "ext_register_operand" "")
8042         (and (match_dup 0)
8043              (const_int -65281)))
8044    (clobber (reg:CC FLAGS_REG))]
8045   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8046   [(parallel [(set (zero_extract:SI (match_dup 0)
8047                                     (const_int 8)
8048                                     (const_int 8))
8049                    (xor:SI 
8050                      (zero_extract:SI (match_dup 0)
8051                                       (const_int 8)
8052                                       (const_int 8))
8053                      (zero_extract:SI (match_dup 0)
8054                                       (const_int 8)
8055                                       (const_int 8))))
8056               (clobber (reg:CC FLAGS_REG))])]
8057   "operands[0] = gen_lowpart (SImode, operands[0]);")
8059 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8060 (define_insn "*andsi_1_zext"
8061   [(set (match_operand:DI 0 "register_operand" "=r")
8062         (zero_extend:DI
8063           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8064                   (match_operand:SI 2 "general_operand" "rim"))))
8065    (clobber (reg:CC FLAGS_REG))]
8066   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8067   "and{l}\t{%2, %k0|%k0, %2}"
8068   [(set_attr "type" "alu")
8069    (set_attr "mode" "SI")])
8071 (define_insn "*andsi_2"
8072   [(set (reg FLAGS_REG)
8073         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8074                          (match_operand:SI 2 "general_operand" "rim,ri"))
8075                  (const_int 0)))
8076    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8077         (and:SI (match_dup 1) (match_dup 2)))]
8078   "ix86_match_ccmode (insn, CCNOmode)
8079    && ix86_binary_operator_ok (AND, SImode, operands)"
8080   "and{l}\t{%2, %0|%0, %2}"
8081   [(set_attr "type" "alu")
8082    (set_attr "mode" "SI")])
8084 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8085 (define_insn "*andsi_2_zext"
8086   [(set (reg FLAGS_REG)
8087         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8088                          (match_operand:SI 2 "general_operand" "rim"))
8089                  (const_int 0)))
8090    (set (match_operand:DI 0 "register_operand" "=r")
8091         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8092   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8093    && ix86_binary_operator_ok (AND, SImode, operands)"
8094   "and{l}\t{%2, %k0|%k0, %2}"
8095   [(set_attr "type" "alu")
8096    (set_attr "mode" "SI")])
8098 (define_expand "andhi3"
8099   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8100         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8101                 (match_operand:HI 2 "general_operand" "")))
8102    (clobber (reg:CC FLAGS_REG))]
8103   "TARGET_HIMODE_MATH"
8104   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8106 (define_insn "*andhi_1"
8107   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8108         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8109                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8110    (clobber (reg:CC FLAGS_REG))]
8111   "ix86_binary_operator_ok (AND, HImode, operands)"
8113   switch (get_attr_type (insn))
8114     {
8115     case TYPE_IMOVX:
8116       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8117       gcc_assert (INTVAL (operands[2]) == 0xff);
8118       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8120     default:
8121       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8123       return "and{w}\t{%2, %0|%0, %2}";
8124     }
8126   [(set_attr "type" "alu,alu,imovx")
8127    (set_attr "length_immediate" "*,*,0")
8128    (set_attr "mode" "HI,HI,SI")])
8130 (define_insn "*andhi_2"
8131   [(set (reg FLAGS_REG)
8132         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8133                          (match_operand:HI 2 "general_operand" "rim,ri"))
8134                  (const_int 0)))
8135    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8136         (and:HI (match_dup 1) (match_dup 2)))]
8137   "ix86_match_ccmode (insn, CCNOmode)
8138    && ix86_binary_operator_ok (AND, HImode, operands)"
8139   "and{w}\t{%2, %0|%0, %2}"
8140   [(set_attr "type" "alu")
8141    (set_attr "mode" "HI")])
8143 (define_expand "andqi3"
8144   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8145         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8146                 (match_operand:QI 2 "general_operand" "")))
8147    (clobber (reg:CC FLAGS_REG))]
8148   "TARGET_QIMODE_MATH"
8149   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8151 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8152 (define_insn "*andqi_1"
8153   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8154         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8155                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8156    (clobber (reg:CC FLAGS_REG))]
8157   "ix86_binary_operator_ok (AND, QImode, operands)"
8158   "@
8159    and{b}\t{%2, %0|%0, %2}
8160    and{b}\t{%2, %0|%0, %2}
8161    and{l}\t{%k2, %k0|%k0, %k2}"
8162   [(set_attr "type" "alu")
8163    (set_attr "mode" "QI,QI,SI")])
8165 (define_insn "*andqi_1_slp"
8166   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8167         (and:QI (match_dup 0)
8168                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8169    (clobber (reg:CC FLAGS_REG))]
8170   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8171    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8172   "and{b}\t{%1, %0|%0, %1}"
8173   [(set_attr "type" "alu1")
8174    (set_attr "mode" "QI")])
8176 (define_insn "*andqi_2_maybe_si"
8177   [(set (reg FLAGS_REG)
8178         (compare (and:QI
8179                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8180                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8181                  (const_int 0)))
8182    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8183         (and:QI (match_dup 1) (match_dup 2)))]
8184   "ix86_binary_operator_ok (AND, QImode, operands)
8185    && ix86_match_ccmode (insn,
8186                          GET_CODE (operands[2]) == CONST_INT
8187                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8189   if (which_alternative == 2)
8190     {
8191       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8192         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8193       return "and{l}\t{%2, %k0|%k0, %2}";
8194     }
8195   return "and{b}\t{%2, %0|%0, %2}";
8197   [(set_attr "type" "alu")
8198    (set_attr "mode" "QI,QI,SI")])
8200 (define_insn "*andqi_2"
8201   [(set (reg FLAGS_REG)
8202         (compare (and:QI
8203                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8204                    (match_operand:QI 2 "general_operand" "qim,qi"))
8205                  (const_int 0)))
8206    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8207         (and:QI (match_dup 1) (match_dup 2)))]
8208   "ix86_match_ccmode (insn, CCNOmode)
8209    && ix86_binary_operator_ok (AND, QImode, operands)"
8210   "and{b}\t{%2, %0|%0, %2}"
8211   [(set_attr "type" "alu")
8212    (set_attr "mode" "QI")])
8214 (define_insn "*andqi_2_slp"
8215   [(set (reg FLAGS_REG)
8216         (compare (and:QI
8217                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8218                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8219                  (const_int 0)))
8220    (set (strict_low_part (match_dup 0))
8221         (and:QI (match_dup 0) (match_dup 1)))]
8222   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8223    && ix86_match_ccmode (insn, CCNOmode)
8224    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8225   "and{b}\t{%1, %0|%0, %1}"
8226   [(set_attr "type" "alu1")
8227    (set_attr "mode" "QI")])
8229 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8230 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8231 ;; for a QImode operand, which of course failed.
8233 (define_insn "andqi_ext_0"
8234   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8235                          (const_int 8)
8236                          (const_int 8))
8237         (and:SI 
8238           (zero_extract:SI
8239             (match_operand 1 "ext_register_operand" "0")
8240             (const_int 8)
8241             (const_int 8))
8242           (match_operand 2 "const_int_operand" "n")))
8243    (clobber (reg:CC FLAGS_REG))]
8244   ""
8245   "and{b}\t{%2, %h0|%h0, %2}"
8246   [(set_attr "type" "alu")
8247    (set_attr "length_immediate" "1")
8248    (set_attr "mode" "QI")])
8250 ;; Generated by peephole translating test to and.  This shows up
8251 ;; often in fp comparisons.
8253 (define_insn "*andqi_ext_0_cc"
8254   [(set (reg FLAGS_REG)
8255         (compare
8256           (and:SI
8257             (zero_extract:SI
8258               (match_operand 1 "ext_register_operand" "0")
8259               (const_int 8)
8260               (const_int 8))
8261             (match_operand 2 "const_int_operand" "n"))
8262           (const_int 0)))
8263    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8264                          (const_int 8)
8265                          (const_int 8))
8266         (and:SI 
8267           (zero_extract:SI
8268             (match_dup 1)
8269             (const_int 8)
8270             (const_int 8))
8271           (match_dup 2)))]
8272   "ix86_match_ccmode (insn, CCNOmode)"
8273   "and{b}\t{%2, %h0|%h0, %2}"
8274   [(set_attr "type" "alu")
8275    (set_attr "length_immediate" "1")
8276    (set_attr "mode" "QI")])
8278 (define_insn "*andqi_ext_1"
8279   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8280                          (const_int 8)
8281                          (const_int 8))
8282         (and:SI 
8283           (zero_extract:SI
8284             (match_operand 1 "ext_register_operand" "0")
8285             (const_int 8)
8286             (const_int 8))
8287           (zero_extend:SI
8288             (match_operand:QI 2 "general_operand" "Qm"))))
8289    (clobber (reg:CC FLAGS_REG))]
8290   "!TARGET_64BIT"
8291   "and{b}\t{%2, %h0|%h0, %2}"
8292   [(set_attr "type" "alu")
8293    (set_attr "length_immediate" "0")
8294    (set_attr "mode" "QI")])
8296 (define_insn "*andqi_ext_1_rex64"
8297   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8298                          (const_int 8)
8299                          (const_int 8))
8300         (and:SI 
8301           (zero_extract:SI
8302             (match_operand 1 "ext_register_operand" "0")
8303             (const_int 8)
8304             (const_int 8))
8305           (zero_extend:SI
8306             (match_operand 2 "ext_register_operand" "Q"))))
8307    (clobber (reg:CC FLAGS_REG))]
8308   "TARGET_64BIT"
8309   "and{b}\t{%2, %h0|%h0, %2}"
8310   [(set_attr "type" "alu")
8311    (set_attr "length_immediate" "0")
8312    (set_attr "mode" "QI")])
8314 (define_insn "*andqi_ext_2"
8315   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8316                          (const_int 8)
8317                          (const_int 8))
8318         (and:SI
8319           (zero_extract:SI
8320             (match_operand 1 "ext_register_operand" "%0")
8321             (const_int 8)
8322             (const_int 8))
8323           (zero_extract:SI
8324             (match_operand 2 "ext_register_operand" "Q")
8325             (const_int 8)
8326             (const_int 8))))
8327    (clobber (reg:CC FLAGS_REG))]
8328   ""
8329   "and{b}\t{%h2, %h0|%h0, %h2}"
8330   [(set_attr "type" "alu")
8331    (set_attr "length_immediate" "0")
8332    (set_attr "mode" "QI")])
8334 ;; Convert wide AND instructions with immediate operand to shorter QImode
8335 ;; equivalents when possible.
8336 ;; Don't do the splitting with memory operands, since it introduces risk
8337 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8338 ;; for size, but that can (should?) be handled by generic code instead.
8339 (define_split
8340   [(set (match_operand 0 "register_operand" "")
8341         (and (match_operand 1 "register_operand" "")
8342              (match_operand 2 "const_int_operand" "")))
8343    (clobber (reg:CC FLAGS_REG))]
8344    "reload_completed
8345     && QI_REG_P (operands[0])
8346     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8347     && !(~INTVAL (operands[2]) & ~(255 << 8))
8348     && GET_MODE (operands[0]) != QImode"
8349   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8350                    (and:SI (zero_extract:SI (match_dup 1)
8351                                             (const_int 8) (const_int 8))
8352                            (match_dup 2)))
8353               (clobber (reg:CC FLAGS_REG))])]
8354   "operands[0] = gen_lowpart (SImode, operands[0]);
8355    operands[1] = gen_lowpart (SImode, operands[1]);
8356    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8358 ;; Since AND can be encoded with sign extended immediate, this is only
8359 ;; profitable when 7th bit is not set.
8360 (define_split
8361   [(set (match_operand 0 "register_operand" "")
8362         (and (match_operand 1 "general_operand" "")
8363              (match_operand 2 "const_int_operand" "")))
8364    (clobber (reg:CC FLAGS_REG))]
8365    "reload_completed
8366     && ANY_QI_REG_P (operands[0])
8367     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8368     && !(~INTVAL (operands[2]) & ~255)
8369     && !(INTVAL (operands[2]) & 128)
8370     && GET_MODE (operands[0]) != QImode"
8371   [(parallel [(set (strict_low_part (match_dup 0))
8372                    (and:QI (match_dup 1)
8373                            (match_dup 2)))
8374               (clobber (reg:CC FLAGS_REG))])]
8375   "operands[0] = gen_lowpart (QImode, operands[0]);
8376    operands[1] = gen_lowpart (QImode, operands[1]);
8377    operands[2] = gen_lowpart (QImode, operands[2]);")
8379 ;; Logical inclusive OR instructions
8381 ;; %%% This used to optimize known byte-wide and operations to memory.
8382 ;; If this is considered useful, it should be done with splitters.
8384 (define_expand "iordi3"
8385   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8386         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8387                 (match_operand:DI 2 "x86_64_general_operand" "")))
8388    (clobber (reg:CC FLAGS_REG))]
8389   "TARGET_64BIT"
8390   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8392 (define_insn "*iordi_1_rex64"
8393   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8394         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8395                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8396    (clobber (reg:CC FLAGS_REG))]
8397   "TARGET_64BIT
8398    && ix86_binary_operator_ok (IOR, DImode, operands)"
8399   "or{q}\t{%2, %0|%0, %2}"
8400   [(set_attr "type" "alu")
8401    (set_attr "mode" "DI")])
8403 (define_insn "*iordi_2_rex64"
8404   [(set (reg FLAGS_REG)
8405         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8406                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8407                  (const_int 0)))
8408    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8409         (ior:DI (match_dup 1) (match_dup 2)))]
8410   "TARGET_64BIT
8411    && ix86_match_ccmode (insn, CCNOmode)
8412    && ix86_binary_operator_ok (IOR, DImode, operands)"
8413   "or{q}\t{%2, %0|%0, %2}"
8414   [(set_attr "type" "alu")
8415    (set_attr "mode" "DI")])
8417 (define_insn "*iordi_3_rex64"
8418   [(set (reg FLAGS_REG)
8419         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8420                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8421                  (const_int 0)))
8422    (clobber (match_scratch:DI 0 "=r"))]
8423   "TARGET_64BIT
8424    && ix86_match_ccmode (insn, CCNOmode)
8425    && ix86_binary_operator_ok (IOR, DImode, operands)"
8426   "or{q}\t{%2, %0|%0, %2}"
8427   [(set_attr "type" "alu")
8428    (set_attr "mode" "DI")])
8431 (define_expand "iorsi3"
8432   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8433         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8434                 (match_operand:SI 2 "general_operand" "")))
8435    (clobber (reg:CC FLAGS_REG))]
8436   ""
8437   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8439 (define_insn "*iorsi_1"
8440   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8441         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8442                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8443    (clobber (reg:CC FLAGS_REG))]
8444   "ix86_binary_operator_ok (IOR, SImode, operands)"
8445   "or{l}\t{%2, %0|%0, %2}"
8446   [(set_attr "type" "alu")
8447    (set_attr "mode" "SI")])
8449 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8450 (define_insn "*iorsi_1_zext"
8451   [(set (match_operand:DI 0 "register_operand" "=rm")
8452         (zero_extend:DI
8453           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8454                   (match_operand:SI 2 "general_operand" "rim"))))
8455    (clobber (reg:CC FLAGS_REG))]
8456   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8457   "or{l}\t{%2, %k0|%k0, %2}"
8458   [(set_attr "type" "alu")
8459    (set_attr "mode" "SI")])
8461 (define_insn "*iorsi_1_zext_imm"
8462   [(set (match_operand:DI 0 "register_operand" "=rm")
8463         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8464                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8465    (clobber (reg:CC FLAGS_REG))]
8466   "TARGET_64BIT"
8467   "or{l}\t{%2, %k0|%k0, %2}"
8468   [(set_attr "type" "alu")
8469    (set_attr "mode" "SI")])
8471 (define_insn "*iorsi_2"
8472   [(set (reg FLAGS_REG)
8473         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8474                          (match_operand:SI 2 "general_operand" "rim,ri"))
8475                  (const_int 0)))
8476    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8477         (ior:SI (match_dup 1) (match_dup 2)))]
8478   "ix86_match_ccmode (insn, CCNOmode)
8479    && ix86_binary_operator_ok (IOR, SImode, operands)"
8480   "or{l}\t{%2, %0|%0, %2}"
8481   [(set_attr "type" "alu")
8482    (set_attr "mode" "SI")])
8484 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8485 ;; ??? Special case for immediate operand is missing - it is tricky.
8486 (define_insn "*iorsi_2_zext"
8487   [(set (reg FLAGS_REG)
8488         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8489                          (match_operand:SI 2 "general_operand" "rim"))
8490                  (const_int 0)))
8491    (set (match_operand:DI 0 "register_operand" "=r")
8492         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8493   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8494    && ix86_binary_operator_ok (IOR, SImode, operands)"
8495   "or{l}\t{%2, %k0|%k0, %2}"
8496   [(set_attr "type" "alu")
8497    (set_attr "mode" "SI")])
8499 (define_insn "*iorsi_2_zext_imm"
8500   [(set (reg FLAGS_REG)
8501         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8502                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8503                  (const_int 0)))
8504    (set (match_operand:DI 0 "register_operand" "=r")
8505         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8506   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8507    && ix86_binary_operator_ok (IOR, SImode, operands)"
8508   "or{l}\t{%2, %k0|%k0, %2}"
8509   [(set_attr "type" "alu")
8510    (set_attr "mode" "SI")])
8512 (define_insn "*iorsi_3"
8513   [(set (reg FLAGS_REG)
8514         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8515                          (match_operand:SI 2 "general_operand" "rim"))
8516                  (const_int 0)))
8517    (clobber (match_scratch:SI 0 "=r"))]
8518   "ix86_match_ccmode (insn, CCNOmode)
8519    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8520   "or{l}\t{%2, %0|%0, %2}"
8521   [(set_attr "type" "alu")
8522    (set_attr "mode" "SI")])
8524 (define_expand "iorhi3"
8525   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8526         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8527                 (match_operand:HI 2 "general_operand" "")))
8528    (clobber (reg:CC FLAGS_REG))]
8529   "TARGET_HIMODE_MATH"
8530   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8532 (define_insn "*iorhi_1"
8533   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8534         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8535                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "ix86_binary_operator_ok (IOR, HImode, operands)"
8538   "or{w}\t{%2, %0|%0, %2}"
8539   [(set_attr "type" "alu")
8540    (set_attr "mode" "HI")])
8542 (define_insn "*iorhi_2"
8543   [(set (reg FLAGS_REG)
8544         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8545                          (match_operand:HI 2 "general_operand" "rim,ri"))
8546                  (const_int 0)))
8547    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8548         (ior:HI (match_dup 1) (match_dup 2)))]
8549   "ix86_match_ccmode (insn, CCNOmode)
8550    && ix86_binary_operator_ok (IOR, HImode, operands)"
8551   "or{w}\t{%2, %0|%0, %2}"
8552   [(set_attr "type" "alu")
8553    (set_attr "mode" "HI")])
8555 (define_insn "*iorhi_3"
8556   [(set (reg FLAGS_REG)
8557         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8558                          (match_operand:HI 2 "general_operand" "rim"))
8559                  (const_int 0)))
8560    (clobber (match_scratch:HI 0 "=r"))]
8561   "ix86_match_ccmode (insn, CCNOmode)
8562    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8563   "or{w}\t{%2, %0|%0, %2}"
8564   [(set_attr "type" "alu")
8565    (set_attr "mode" "HI")])
8567 (define_expand "iorqi3"
8568   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8569         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8570                 (match_operand:QI 2 "general_operand" "")))
8571    (clobber (reg:CC FLAGS_REG))]
8572   "TARGET_QIMODE_MATH"
8573   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8575 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8576 (define_insn "*iorqi_1"
8577   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8578         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8579                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8580    (clobber (reg:CC FLAGS_REG))]
8581   "ix86_binary_operator_ok (IOR, QImode, operands)"
8582   "@
8583    or{b}\t{%2, %0|%0, %2}
8584    or{b}\t{%2, %0|%0, %2}
8585    or{l}\t{%k2, %k0|%k0, %k2}"
8586   [(set_attr "type" "alu")
8587    (set_attr "mode" "QI,QI,SI")])
8589 (define_insn "*iorqi_1_slp"
8590   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8591         (ior:QI (match_dup 0)
8592                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8593    (clobber (reg:CC FLAGS_REG))]
8594   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8595    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8596   "or{b}\t{%1, %0|%0, %1}"
8597   [(set_attr "type" "alu1")
8598    (set_attr "mode" "QI")])
8600 (define_insn "*iorqi_2"
8601   [(set (reg FLAGS_REG)
8602         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8603                          (match_operand:QI 2 "general_operand" "qim,qi"))
8604                  (const_int 0)))
8605    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8606         (ior:QI (match_dup 1) (match_dup 2)))]
8607   "ix86_match_ccmode (insn, CCNOmode)
8608    && ix86_binary_operator_ok (IOR, QImode, operands)"
8609   "or{b}\t{%2, %0|%0, %2}"
8610   [(set_attr "type" "alu")
8611    (set_attr "mode" "QI")])
8613 (define_insn "*iorqi_2_slp"
8614   [(set (reg FLAGS_REG)
8615         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8616                          (match_operand:QI 1 "general_operand" "qim,qi"))
8617                  (const_int 0)))
8618    (set (strict_low_part (match_dup 0))
8619         (ior:QI (match_dup 0) (match_dup 1)))]
8620   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8621    && ix86_match_ccmode (insn, CCNOmode)
8622    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8623   "or{b}\t{%1, %0|%0, %1}"
8624   [(set_attr "type" "alu1")
8625    (set_attr "mode" "QI")])
8627 (define_insn "*iorqi_3"
8628   [(set (reg FLAGS_REG)
8629         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8630                          (match_operand:QI 2 "general_operand" "qim"))
8631                  (const_int 0)))
8632    (clobber (match_scratch:QI 0 "=q"))]
8633   "ix86_match_ccmode (insn, CCNOmode)
8634    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8635   "or{b}\t{%2, %0|%0, %2}"
8636   [(set_attr "type" "alu")
8637    (set_attr "mode" "QI")])
8639 (define_insn "iorqi_ext_0"
8640   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8641                          (const_int 8)
8642                          (const_int 8))
8643         (ior:SI 
8644           (zero_extract:SI
8645             (match_operand 1 "ext_register_operand" "0")
8646             (const_int 8)
8647             (const_int 8))
8648           (match_operand 2 "const_int_operand" "n")))
8649    (clobber (reg:CC FLAGS_REG))]
8650   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8651   "or{b}\t{%2, %h0|%h0, %2}"
8652   [(set_attr "type" "alu")
8653    (set_attr "length_immediate" "1")
8654    (set_attr "mode" "QI")])
8656 (define_insn "*iorqi_ext_1"
8657   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8658                          (const_int 8)
8659                          (const_int 8))
8660         (ior:SI 
8661           (zero_extract:SI
8662             (match_operand 1 "ext_register_operand" "0")
8663             (const_int 8)
8664             (const_int 8))
8665           (zero_extend:SI
8666             (match_operand:QI 2 "general_operand" "Qm"))))
8667    (clobber (reg:CC FLAGS_REG))]
8668   "!TARGET_64BIT
8669    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8670   "or{b}\t{%2, %h0|%h0, %2}"
8671   [(set_attr "type" "alu")
8672    (set_attr "length_immediate" "0")
8673    (set_attr "mode" "QI")])
8675 (define_insn "*iorqi_ext_1_rex64"
8676   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8677                          (const_int 8)
8678                          (const_int 8))
8679         (ior:SI 
8680           (zero_extract:SI
8681             (match_operand 1 "ext_register_operand" "0")
8682             (const_int 8)
8683             (const_int 8))
8684           (zero_extend:SI
8685             (match_operand 2 "ext_register_operand" "Q"))))
8686    (clobber (reg:CC FLAGS_REG))]
8687   "TARGET_64BIT
8688    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8689   "or{b}\t{%2, %h0|%h0, %2}"
8690   [(set_attr "type" "alu")
8691    (set_attr "length_immediate" "0")
8692    (set_attr "mode" "QI")])
8694 (define_insn "*iorqi_ext_2"
8695   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8696                          (const_int 8)
8697                          (const_int 8))
8698         (ior:SI 
8699           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8700                            (const_int 8)
8701                            (const_int 8))
8702           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8703                            (const_int 8)
8704                            (const_int 8))))
8705    (clobber (reg:CC FLAGS_REG))]
8706   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8707   "ior{b}\t{%h2, %h0|%h0, %h2}"
8708   [(set_attr "type" "alu")
8709    (set_attr "length_immediate" "0")
8710    (set_attr "mode" "QI")])
8712 (define_split
8713   [(set (match_operand 0 "register_operand" "")
8714         (ior (match_operand 1 "register_operand" "")
8715              (match_operand 2 "const_int_operand" "")))
8716    (clobber (reg:CC FLAGS_REG))]
8717    "reload_completed
8718     && QI_REG_P (operands[0])
8719     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8720     && !(INTVAL (operands[2]) & ~(255 << 8))
8721     && GET_MODE (operands[0]) != QImode"
8722   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8723                    (ior:SI (zero_extract:SI (match_dup 1)
8724                                             (const_int 8) (const_int 8))
8725                            (match_dup 2)))
8726               (clobber (reg:CC FLAGS_REG))])]
8727   "operands[0] = gen_lowpart (SImode, operands[0]);
8728    operands[1] = gen_lowpart (SImode, operands[1]);
8729    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8731 ;; Since OR can be encoded with sign extended immediate, this is only
8732 ;; profitable when 7th bit is set.
8733 (define_split
8734   [(set (match_operand 0 "register_operand" "")
8735         (ior (match_operand 1 "general_operand" "")
8736              (match_operand 2 "const_int_operand" "")))
8737    (clobber (reg:CC FLAGS_REG))]
8738    "reload_completed
8739     && ANY_QI_REG_P (operands[0])
8740     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8741     && !(INTVAL (operands[2]) & ~255)
8742     && (INTVAL (operands[2]) & 128)
8743     && GET_MODE (operands[0]) != QImode"
8744   [(parallel [(set (strict_low_part (match_dup 0))
8745                    (ior:QI (match_dup 1)
8746                            (match_dup 2)))
8747               (clobber (reg:CC FLAGS_REG))])]
8748   "operands[0] = gen_lowpart (QImode, operands[0]);
8749    operands[1] = gen_lowpart (QImode, operands[1]);
8750    operands[2] = gen_lowpart (QImode, operands[2]);")
8752 ;; Logical XOR instructions
8754 ;; %%% This used to optimize known byte-wide and operations to memory.
8755 ;; If this is considered useful, it should be done with splitters.
8757 (define_expand "xordi3"
8758   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8759         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8760                 (match_operand:DI 2 "x86_64_general_operand" "")))
8761    (clobber (reg:CC FLAGS_REG))]
8762   "TARGET_64BIT"
8763   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8765 (define_insn "*xordi_1_rex64"
8766   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8767         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8768                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "TARGET_64BIT
8771    && ix86_binary_operator_ok (XOR, DImode, operands)"
8772   "@
8773    xor{q}\t{%2, %0|%0, %2}
8774    xor{q}\t{%2, %0|%0, %2}"
8775   [(set_attr "type" "alu")
8776    (set_attr "mode" "DI,DI")])
8778 (define_insn "*xordi_2_rex64"
8779   [(set (reg FLAGS_REG)
8780         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8781                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8782                  (const_int 0)))
8783    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8784         (xor:DI (match_dup 1) (match_dup 2)))]
8785   "TARGET_64BIT
8786    && ix86_match_ccmode (insn, CCNOmode)
8787    && ix86_binary_operator_ok (XOR, DImode, operands)"
8788   "@
8789    xor{q}\t{%2, %0|%0, %2}
8790    xor{q}\t{%2, %0|%0, %2}"
8791   [(set_attr "type" "alu")
8792    (set_attr "mode" "DI,DI")])
8794 (define_insn "*xordi_3_rex64"
8795   [(set (reg FLAGS_REG)
8796         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8797                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8798                  (const_int 0)))
8799    (clobber (match_scratch:DI 0 "=r"))]
8800   "TARGET_64BIT
8801    && ix86_match_ccmode (insn, CCNOmode)
8802    && ix86_binary_operator_ok (XOR, DImode, operands)"
8803   "xor{q}\t{%2, %0|%0, %2}"
8804   [(set_attr "type" "alu")
8805    (set_attr "mode" "DI")])
8807 (define_expand "xorsi3"
8808   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8809         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8810                 (match_operand:SI 2 "general_operand" "")))
8811    (clobber (reg:CC FLAGS_REG))]
8812   ""
8813   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8815 (define_insn "*xorsi_1"
8816   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8817         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8818                 (match_operand:SI 2 "general_operand" "ri,rm")))
8819    (clobber (reg:CC FLAGS_REG))]
8820   "ix86_binary_operator_ok (XOR, SImode, operands)"
8821   "xor{l}\t{%2, %0|%0, %2}"
8822   [(set_attr "type" "alu")
8823    (set_attr "mode" "SI")])
8825 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8826 ;; Add speccase for immediates
8827 (define_insn "*xorsi_1_zext"
8828   [(set (match_operand:DI 0 "register_operand" "=r")
8829         (zero_extend:DI
8830           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8831                   (match_operand:SI 2 "general_operand" "rim"))))
8832    (clobber (reg:CC FLAGS_REG))]
8833   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8834   "xor{l}\t{%2, %k0|%k0, %2}"
8835   [(set_attr "type" "alu")
8836    (set_attr "mode" "SI")])
8838 (define_insn "*xorsi_1_zext_imm"
8839   [(set (match_operand:DI 0 "register_operand" "=r")
8840         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8841                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8842    (clobber (reg:CC FLAGS_REG))]
8843   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8844   "xor{l}\t{%2, %k0|%k0, %2}"
8845   [(set_attr "type" "alu")
8846    (set_attr "mode" "SI")])
8848 (define_insn "*xorsi_2"
8849   [(set (reg FLAGS_REG)
8850         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8851                          (match_operand:SI 2 "general_operand" "rim,ri"))
8852                  (const_int 0)))
8853    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8854         (xor:SI (match_dup 1) (match_dup 2)))]
8855   "ix86_match_ccmode (insn, CCNOmode)
8856    && ix86_binary_operator_ok (XOR, SImode, operands)"
8857   "xor{l}\t{%2, %0|%0, %2}"
8858   [(set_attr "type" "alu")
8859    (set_attr "mode" "SI")])
8861 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8862 ;; ??? Special case for immediate operand is missing - it is tricky.
8863 (define_insn "*xorsi_2_zext"
8864   [(set (reg FLAGS_REG)
8865         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8866                          (match_operand:SI 2 "general_operand" "rim"))
8867                  (const_int 0)))
8868    (set (match_operand:DI 0 "register_operand" "=r")
8869         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8870   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8871    && ix86_binary_operator_ok (XOR, SImode, operands)"
8872   "xor{l}\t{%2, %k0|%k0, %2}"
8873   [(set_attr "type" "alu")
8874    (set_attr "mode" "SI")])
8876 (define_insn "*xorsi_2_zext_imm"
8877   [(set (reg FLAGS_REG)
8878         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8879                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8880                  (const_int 0)))
8881    (set (match_operand:DI 0 "register_operand" "=r")
8882         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8883   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8884    && ix86_binary_operator_ok (XOR, SImode, operands)"
8885   "xor{l}\t{%2, %k0|%k0, %2}"
8886   [(set_attr "type" "alu")
8887    (set_attr "mode" "SI")])
8889 (define_insn "*xorsi_3"
8890   [(set (reg FLAGS_REG)
8891         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8892                          (match_operand:SI 2 "general_operand" "rim"))
8893                  (const_int 0)))
8894    (clobber (match_scratch:SI 0 "=r"))]
8895   "ix86_match_ccmode (insn, CCNOmode)
8896    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8897   "xor{l}\t{%2, %0|%0, %2}"
8898   [(set_attr "type" "alu")
8899    (set_attr "mode" "SI")])
8901 (define_expand "xorhi3"
8902   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8903         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8904                 (match_operand:HI 2 "general_operand" "")))
8905    (clobber (reg:CC FLAGS_REG))]
8906   "TARGET_HIMODE_MATH"
8907   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8909 (define_insn "*xorhi_1"
8910   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8911         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8912                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8913    (clobber (reg:CC FLAGS_REG))]
8914   "ix86_binary_operator_ok (XOR, HImode, operands)"
8915   "xor{w}\t{%2, %0|%0, %2}"
8916   [(set_attr "type" "alu")
8917    (set_attr "mode" "HI")])
8919 (define_insn "*xorhi_2"
8920   [(set (reg FLAGS_REG)
8921         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8922                          (match_operand:HI 2 "general_operand" "rim,ri"))
8923                  (const_int 0)))
8924    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8925         (xor:HI (match_dup 1) (match_dup 2)))]
8926   "ix86_match_ccmode (insn, CCNOmode)
8927    && ix86_binary_operator_ok (XOR, HImode, operands)"
8928   "xor{w}\t{%2, %0|%0, %2}"
8929   [(set_attr "type" "alu")
8930    (set_attr "mode" "HI")])
8932 (define_insn "*xorhi_3"
8933   [(set (reg FLAGS_REG)
8934         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8935                          (match_operand:HI 2 "general_operand" "rim"))
8936                  (const_int 0)))
8937    (clobber (match_scratch:HI 0 "=r"))]
8938   "ix86_match_ccmode (insn, CCNOmode)
8939    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8940   "xor{w}\t{%2, %0|%0, %2}"
8941   [(set_attr "type" "alu")
8942    (set_attr "mode" "HI")])
8944 (define_expand "xorqi3"
8945   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8946         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8947                 (match_operand:QI 2 "general_operand" "")))
8948    (clobber (reg:CC FLAGS_REG))]
8949   "TARGET_QIMODE_MATH"
8950   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8952 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8953 (define_insn "*xorqi_1"
8954   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8955         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8956                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8957    (clobber (reg:CC FLAGS_REG))]
8958   "ix86_binary_operator_ok (XOR, QImode, operands)"
8959   "@
8960    xor{b}\t{%2, %0|%0, %2}
8961    xor{b}\t{%2, %0|%0, %2}
8962    xor{l}\t{%k2, %k0|%k0, %k2}"
8963   [(set_attr "type" "alu")
8964    (set_attr "mode" "QI,QI,SI")])
8966 (define_insn "*xorqi_1_slp"
8967   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8968         (xor:QI (match_dup 0)
8969                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8970    (clobber (reg:CC FLAGS_REG))]
8971   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8972    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8973   "xor{b}\t{%1, %0|%0, %1}"
8974   [(set_attr "type" "alu1")
8975    (set_attr "mode" "QI")])
8977 (define_insn "xorqi_ext_0"
8978   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8979                          (const_int 8)
8980                          (const_int 8))
8981         (xor:SI 
8982           (zero_extract:SI
8983             (match_operand 1 "ext_register_operand" "0")
8984             (const_int 8)
8985             (const_int 8))
8986           (match_operand 2 "const_int_operand" "n")))
8987    (clobber (reg:CC FLAGS_REG))]
8988   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8989   "xor{b}\t{%2, %h0|%h0, %2}"
8990   [(set_attr "type" "alu")
8991    (set_attr "length_immediate" "1")
8992    (set_attr "mode" "QI")])
8994 (define_insn "*xorqi_ext_1"
8995   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8996                          (const_int 8)
8997                          (const_int 8))
8998         (xor:SI 
8999           (zero_extract:SI
9000             (match_operand 1 "ext_register_operand" "0")
9001             (const_int 8)
9002             (const_int 8))
9003           (zero_extend:SI
9004             (match_operand:QI 2 "general_operand" "Qm"))))
9005    (clobber (reg:CC FLAGS_REG))]
9006   "!TARGET_64BIT
9007    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9008   "xor{b}\t{%2, %h0|%h0, %2}"
9009   [(set_attr "type" "alu")
9010    (set_attr "length_immediate" "0")
9011    (set_attr "mode" "QI")])
9013 (define_insn "*xorqi_ext_1_rex64"
9014   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9015                          (const_int 8)
9016                          (const_int 8))
9017         (xor:SI 
9018           (zero_extract:SI
9019             (match_operand 1 "ext_register_operand" "0")
9020             (const_int 8)
9021             (const_int 8))
9022           (zero_extend:SI
9023             (match_operand 2 "ext_register_operand" "Q"))))
9024    (clobber (reg:CC FLAGS_REG))]
9025   "TARGET_64BIT
9026    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9027   "xor{b}\t{%2, %h0|%h0, %2}"
9028   [(set_attr "type" "alu")
9029    (set_attr "length_immediate" "0")
9030    (set_attr "mode" "QI")])
9032 (define_insn "*xorqi_ext_2"
9033   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9034                          (const_int 8)
9035                          (const_int 8))
9036         (xor:SI 
9037           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9038                            (const_int 8)
9039                            (const_int 8))
9040           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9041                            (const_int 8)
9042                            (const_int 8))))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9045   "xor{b}\t{%h2, %h0|%h0, %h2}"
9046   [(set_attr "type" "alu")
9047    (set_attr "length_immediate" "0")
9048    (set_attr "mode" "QI")])
9050 (define_insn "*xorqi_cc_1"
9051   [(set (reg FLAGS_REG)
9052         (compare
9053           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9054                   (match_operand:QI 2 "general_operand" "qim,qi"))
9055           (const_int 0)))
9056    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9057         (xor:QI (match_dup 1) (match_dup 2)))]
9058   "ix86_match_ccmode (insn, CCNOmode)
9059    && ix86_binary_operator_ok (XOR, QImode, operands)"
9060   "xor{b}\t{%2, %0|%0, %2}"
9061   [(set_attr "type" "alu")
9062    (set_attr "mode" "QI")])
9064 (define_insn "*xorqi_2_slp"
9065   [(set (reg FLAGS_REG)
9066         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9067                          (match_operand:QI 1 "general_operand" "qim,qi"))
9068                  (const_int 0)))
9069    (set (strict_low_part (match_dup 0))
9070         (xor:QI (match_dup 0) (match_dup 1)))]
9071   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9072    && ix86_match_ccmode (insn, CCNOmode)
9073    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9074   "xor{b}\t{%1, %0|%0, %1}"
9075   [(set_attr "type" "alu1")
9076    (set_attr "mode" "QI")])
9078 (define_insn "*xorqi_cc_2"
9079   [(set (reg FLAGS_REG)
9080         (compare
9081           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9082                   (match_operand:QI 2 "general_operand" "qim"))
9083           (const_int 0)))
9084    (clobber (match_scratch:QI 0 "=q"))]
9085   "ix86_match_ccmode (insn, CCNOmode)
9086    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9087   "xor{b}\t{%2, %0|%0, %2}"
9088   [(set_attr "type" "alu")
9089    (set_attr "mode" "QI")])
9091 (define_insn "*xorqi_cc_ext_1"
9092   [(set (reg FLAGS_REG)
9093         (compare
9094           (xor:SI
9095             (zero_extract:SI
9096               (match_operand 1 "ext_register_operand" "0")
9097               (const_int 8)
9098               (const_int 8))
9099             (match_operand:QI 2 "general_operand" "qmn"))
9100           (const_int 0)))
9101    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9102                          (const_int 8)
9103                          (const_int 8))
9104         (xor:SI 
9105           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9106           (match_dup 2)))]
9107   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9108   "xor{b}\t{%2, %h0|%h0, %2}"
9109   [(set_attr "type" "alu")
9110    (set_attr "mode" "QI")])
9112 (define_insn "*xorqi_cc_ext_1_rex64"
9113   [(set (reg FLAGS_REG)
9114         (compare
9115           (xor:SI
9116             (zero_extract:SI
9117               (match_operand 1 "ext_register_operand" "0")
9118               (const_int 8)
9119               (const_int 8))
9120             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9121           (const_int 0)))
9122    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9123                          (const_int 8)
9124                          (const_int 8))
9125         (xor:SI 
9126           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9127           (match_dup 2)))]
9128   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9129   "xor{b}\t{%2, %h0|%h0, %2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "mode" "QI")])
9133 (define_expand "xorqi_cc_ext_1"
9134   [(parallel [
9135      (set (reg:CCNO FLAGS_REG)
9136           (compare:CCNO
9137             (xor:SI
9138               (zero_extract:SI
9139                 (match_operand 1 "ext_register_operand" "")
9140                 (const_int 8)
9141                 (const_int 8))
9142               (match_operand:QI 2 "general_operand" ""))
9143             (const_int 0)))
9144      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9145                            (const_int 8)
9146                            (const_int 8))
9147           (xor:SI 
9148             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9149             (match_dup 2)))])]
9150   ""
9151   "")
9153 (define_split
9154   [(set (match_operand 0 "register_operand" "")
9155         (xor (match_operand 1 "register_operand" "")
9156              (match_operand 2 "const_int_operand" "")))
9157    (clobber (reg:CC FLAGS_REG))]
9158    "reload_completed
9159     && QI_REG_P (operands[0])
9160     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9161     && !(INTVAL (operands[2]) & ~(255 << 8))
9162     && GET_MODE (operands[0]) != QImode"
9163   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9164                    (xor:SI (zero_extract:SI (match_dup 1)
9165                                             (const_int 8) (const_int 8))
9166                            (match_dup 2)))
9167               (clobber (reg:CC FLAGS_REG))])]
9168   "operands[0] = gen_lowpart (SImode, operands[0]);
9169    operands[1] = gen_lowpart (SImode, operands[1]);
9170    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9172 ;; Since XOR can be encoded with sign extended immediate, this is only
9173 ;; profitable when 7th bit is set.
9174 (define_split
9175   [(set (match_operand 0 "register_operand" "")
9176         (xor (match_operand 1 "general_operand" "")
9177              (match_operand 2 "const_int_operand" "")))
9178    (clobber (reg:CC FLAGS_REG))]
9179    "reload_completed
9180     && ANY_QI_REG_P (operands[0])
9181     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9182     && !(INTVAL (operands[2]) & ~255)
9183     && (INTVAL (operands[2]) & 128)
9184     && GET_MODE (operands[0]) != QImode"
9185   [(parallel [(set (strict_low_part (match_dup 0))
9186                    (xor:QI (match_dup 1)
9187                            (match_dup 2)))
9188               (clobber (reg:CC FLAGS_REG))])]
9189   "operands[0] = gen_lowpart (QImode, operands[0]);
9190    operands[1] = gen_lowpart (QImode, operands[1]);
9191    operands[2] = gen_lowpart (QImode, operands[2]);")
9193 ;; Negation instructions
9195 (define_expand "negdi2"
9196   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9197                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9198               (clobber (reg:CC FLAGS_REG))])]
9199   ""
9200   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9202 (define_insn "*negdi2_1"
9203   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9204         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9205    (clobber (reg:CC FLAGS_REG))]
9206   "!TARGET_64BIT
9207    && ix86_unary_operator_ok (NEG, DImode, operands)"
9208   "#")
9210 (define_split
9211   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9212         (neg:DI (match_operand:DI 1 "general_operand" "")))
9213    (clobber (reg:CC FLAGS_REG))]
9214   "!TARGET_64BIT && reload_completed"
9215   [(parallel
9216     [(set (reg:CCZ FLAGS_REG)
9217           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9218      (set (match_dup 0) (neg:SI (match_dup 2)))])
9219    (parallel
9220     [(set (match_dup 1)
9221           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9222                             (match_dup 3))
9223                    (const_int 0)))
9224      (clobber (reg:CC FLAGS_REG))])
9225    (parallel
9226     [(set (match_dup 1)
9227           (neg:SI (match_dup 1)))
9228      (clobber (reg:CC FLAGS_REG))])]
9229   "split_di (operands+1, 1, operands+2, operands+3);
9230    split_di (operands+0, 1, operands+0, operands+1);")
9232 (define_insn "*negdi2_1_rex64"
9233   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9234         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9235    (clobber (reg:CC FLAGS_REG))]
9236   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9237   "neg{q}\t%0"
9238   [(set_attr "type" "negnot")
9239    (set_attr "mode" "DI")])
9241 ;; The problem with neg is that it does not perform (compare x 0),
9242 ;; it really performs (compare 0 x), which leaves us with the zero
9243 ;; flag being the only useful item.
9245 (define_insn "*negdi2_cmpz_rex64"
9246   [(set (reg:CCZ FLAGS_REG)
9247         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9248                      (const_int 0)))
9249    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9250         (neg:DI (match_dup 1)))]
9251   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9252   "neg{q}\t%0"
9253   [(set_attr "type" "negnot")
9254    (set_attr "mode" "DI")])
9257 (define_expand "negsi2"
9258   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9259                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9260               (clobber (reg:CC FLAGS_REG))])]
9261   ""
9262   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9264 (define_insn "*negsi2_1"
9265   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9266         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9267    (clobber (reg:CC FLAGS_REG))]
9268   "ix86_unary_operator_ok (NEG, SImode, operands)"
9269   "neg{l}\t%0"
9270   [(set_attr "type" "negnot")
9271    (set_attr "mode" "SI")])
9273 ;; Combine is quite creative about this pattern.
9274 (define_insn "*negsi2_1_zext"
9275   [(set (match_operand:DI 0 "register_operand" "=r")
9276         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9277                                         (const_int 32)))
9278                      (const_int 32)))
9279    (clobber (reg:CC FLAGS_REG))]
9280   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9281   "neg{l}\t%k0"
9282   [(set_attr "type" "negnot")
9283    (set_attr "mode" "SI")])
9285 ;; The problem with neg is that it does not perform (compare x 0),
9286 ;; it really performs (compare 0 x), which leaves us with the zero
9287 ;; flag being the only useful item.
9289 (define_insn "*negsi2_cmpz"
9290   [(set (reg:CCZ FLAGS_REG)
9291         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9292                      (const_int 0)))
9293    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9294         (neg:SI (match_dup 1)))]
9295   "ix86_unary_operator_ok (NEG, SImode, operands)"
9296   "neg{l}\t%0"
9297   [(set_attr "type" "negnot")
9298    (set_attr "mode" "SI")])
9300 (define_insn "*negsi2_cmpz_zext"
9301   [(set (reg:CCZ FLAGS_REG)
9302         (compare:CCZ (lshiftrt:DI
9303                        (neg:DI (ashift:DI
9304                                  (match_operand:DI 1 "register_operand" "0")
9305                                  (const_int 32)))
9306                        (const_int 32))
9307                      (const_int 0)))
9308    (set (match_operand:DI 0 "register_operand" "=r")
9309         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9310                                         (const_int 32)))
9311                      (const_int 32)))]
9312   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9313   "neg{l}\t%k0"
9314   [(set_attr "type" "negnot")
9315    (set_attr "mode" "SI")])
9317 (define_expand "neghi2"
9318   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9319                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9320               (clobber (reg:CC FLAGS_REG))])]
9321   "TARGET_HIMODE_MATH"
9322   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9324 (define_insn "*neghi2_1"
9325   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9326         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9327    (clobber (reg:CC FLAGS_REG))]
9328   "ix86_unary_operator_ok (NEG, HImode, operands)"
9329   "neg{w}\t%0"
9330   [(set_attr "type" "negnot")
9331    (set_attr "mode" "HI")])
9333 (define_insn "*neghi2_cmpz"
9334   [(set (reg:CCZ FLAGS_REG)
9335         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9336                      (const_int 0)))
9337    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9338         (neg:HI (match_dup 1)))]
9339   "ix86_unary_operator_ok (NEG, HImode, operands)"
9340   "neg{w}\t%0"
9341   [(set_attr "type" "negnot")
9342    (set_attr "mode" "HI")])
9344 (define_expand "negqi2"
9345   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9346                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9347               (clobber (reg:CC FLAGS_REG))])]
9348   "TARGET_QIMODE_MATH"
9349   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9351 (define_insn "*negqi2_1"
9352   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9353         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9354    (clobber (reg:CC FLAGS_REG))]
9355   "ix86_unary_operator_ok (NEG, QImode, operands)"
9356   "neg{b}\t%0"
9357   [(set_attr "type" "negnot")
9358    (set_attr "mode" "QI")])
9360 (define_insn "*negqi2_cmpz"
9361   [(set (reg:CCZ FLAGS_REG)
9362         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9363                      (const_int 0)))
9364    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9365         (neg:QI (match_dup 1)))]
9366   "ix86_unary_operator_ok (NEG, QImode, operands)"
9367   "neg{b}\t%0"
9368   [(set_attr "type" "negnot")
9369    (set_attr "mode" "QI")])
9371 ;; Changing of sign for FP values is doable using integer unit too.
9373 (define_expand "negsf2"
9374   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9375         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9376   "TARGET_80387 || TARGET_SSE_MATH"
9377   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9379 (define_expand "abssf2"
9380   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9381         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9382   "TARGET_80387 || TARGET_SSE_MATH"
9383   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9385 (define_insn "*absnegsf2_mixed"
9386   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x#f,x#f,f#x,rm")
9387         (match_operator:SF 3 "absneg_operator"
9388           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x#f,0  ,0")]))
9389    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0  ,X  ,X"))
9390    (clobber (reg:CC FLAGS_REG))]
9391   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9392    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9393   "#")
9395 (define_insn "*absnegsf2_sse"
9396   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9397         (match_operator:SF 3 "absneg_operator"
9398           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9399    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9400    (clobber (reg:CC FLAGS_REG))]
9401   "TARGET_SSE_MATH
9402    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9403   "#")
9405 (define_insn "*absnegsf2_i387"
9406   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9407         (match_operator:SF 3 "absneg_operator"
9408           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9409    (use (match_operand 2 "" ""))
9410    (clobber (reg:CC FLAGS_REG))]
9411   "TARGET_80387 && !TARGET_SSE_MATH
9412    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9413   "#")
9415 (define_expand "copysignsf3"
9416   [(match_operand:SF 0 "register_operand" "")
9417    (match_operand:SF 1 "nonmemory_operand" "")
9418    (match_operand:SF 2 "register_operand" "")]
9419   "TARGET_SSE_MATH"
9421   ix86_expand_copysign (operands);
9422   DONE;
9425 (define_insn_and_split "copysignsf3_const"
9426   [(set (match_operand:SF 0 "register_operand"          "=x")
9427         (unspec:SF
9428           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9429            (match_operand:SF 2 "register_operand"       "0")
9430            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9431           UNSPEC_COPYSIGN))]
9432   "TARGET_SSE_MATH"
9433   "#"
9434   "&& reload_completed"
9435   [(const_int 0)]
9437   ix86_split_copysign_const (operands);
9438   DONE;
9441 (define_insn "copysignsf3_var"
9442   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9443         (unspec:SF
9444           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9445            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9446            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9447            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9448           UNSPEC_COPYSIGN))
9449    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9450   "TARGET_SSE_MATH"
9451   "#")
9453 (define_split
9454   [(set (match_operand:SF 0 "register_operand" "")
9455         (unspec:SF
9456           [(match_operand:SF 2 "register_operand" "")
9457            (match_operand:SF 3 "register_operand" "")
9458            (match_operand:V4SF 4 "" "")
9459            (match_operand:V4SF 5 "" "")]
9460           UNSPEC_COPYSIGN))
9461    (clobber (match_scratch:V4SF 1 ""))]
9462   "TARGET_SSE_MATH && reload_completed"
9463   [(const_int 0)]
9465   ix86_split_copysign_var (operands);
9466   DONE;
9469 (define_expand "negdf2"
9470   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9471         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9472   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9473   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9475 (define_expand "absdf2"
9476   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9477         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9478   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9479   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9481 (define_insn "*absnegdf2_mixed"
9482   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y#f,Y#f,f#Y,rm")
9483         (match_operator:DF 3 "absneg_operator"
9484           [(match_operand:DF 1 "nonimmediate_operand" "0   ,Y#f,0  ,0")]))
9485    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym  ,0  ,X  ,X"))
9486    (clobber (reg:CC FLAGS_REG))]
9487   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9488    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9489   "#")
9491 (define_insn "*absnegdf2_sse"
9492   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9493         (match_operator:DF 3 "absneg_operator"
9494           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9495    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X"))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "TARGET_SSE2 && TARGET_SSE_MATH
9498    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9499   "#")
9501 (define_insn "*absnegdf2_i387"
9502   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9503         (match_operator:DF 3 "absneg_operator"
9504           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9505    (use (match_operand 2 "" ""))
9506    (clobber (reg:CC FLAGS_REG))]
9507   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9508    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9509   "#")
9511 (define_expand "copysigndf3"
9512   [(match_operand:DF 0 "register_operand" "")
9513    (match_operand:DF 1 "nonmemory_operand" "")
9514    (match_operand:DF 2 "register_operand" "")]
9515   "TARGET_SSE2 && TARGET_SSE_MATH"
9517   ix86_expand_copysign (operands);
9518   DONE;
9521 (define_insn_and_split "copysigndf3_const"
9522   [(set (match_operand:DF 0 "register_operand"          "=x")
9523         (unspec:DF
9524           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9525            (match_operand:DF 2 "register_operand"       "0")
9526            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9527           UNSPEC_COPYSIGN))]
9528   "TARGET_SSE2 && TARGET_SSE_MATH"
9529   "#"
9530   "&& reload_completed"
9531   [(const_int 0)]
9533   ix86_split_copysign_const (operands);
9534   DONE;
9537 (define_insn "copysigndf3_var"
9538   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9539         (unspec:DF
9540           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9541            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9542            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9543            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9544           UNSPEC_COPYSIGN))
9545    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9546   "TARGET_SSE2 && TARGET_SSE_MATH"
9547   "#")
9549 (define_split
9550   [(set (match_operand:DF 0 "register_operand" "")
9551         (unspec:DF
9552           [(match_operand:DF 2 "register_operand" "")
9553            (match_operand:DF 3 "register_operand" "")
9554            (match_operand:V2DF 4 "" "")
9555            (match_operand:V2DF 5 "" "")]
9556           UNSPEC_COPYSIGN))
9557    (clobber (match_scratch:V2DF 1 ""))]
9558   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9559   [(const_int 0)]
9561   ix86_split_copysign_var (operands);
9562   DONE;
9565 (define_expand "negxf2"
9566   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9567         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9568   "TARGET_80387"
9569   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9571 (define_expand "absxf2"
9572   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9573         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9574   "TARGET_80387"
9575   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9577 (define_insn "*absnegxf2_i387"
9578   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9579         (match_operator:XF 3 "absneg_operator"
9580           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9581    (use (match_operand 2 "" ""))
9582    (clobber (reg:CC FLAGS_REG))]
9583   "TARGET_80387
9584    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9585   "#")
9587 ;; Splitters for fp abs and neg.
9589 (define_split
9590   [(set (match_operand 0 "fp_register_operand" "")
9591         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9592    (use (match_operand 2 "" ""))
9593    (clobber (reg:CC FLAGS_REG))]
9594   "reload_completed"
9595   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9597 (define_split
9598   [(set (match_operand 0 "register_operand" "")
9599         (match_operator 3 "absneg_operator"
9600           [(match_operand 1 "register_operand" "")]))
9601    (use (match_operand 2 "nonimmediate_operand" ""))
9602    (clobber (reg:CC FLAGS_REG))]
9603   "reload_completed && SSE_REG_P (operands[0])"
9604   [(set (match_dup 0) (match_dup 3))]
9606   enum machine_mode mode = GET_MODE (operands[0]);
9607   enum machine_mode vmode = GET_MODE (operands[2]);
9608   rtx tmp;
9609   
9610   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9611   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9612   if (operands_match_p (operands[0], operands[2]))
9613     {
9614       tmp = operands[1];
9615       operands[1] = operands[2];
9616       operands[2] = tmp;
9617     }
9618   if (GET_CODE (operands[3]) == ABS)
9619     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9620   else
9621     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9622   operands[3] = tmp;
9625 (define_split
9626   [(set (match_operand:SF 0 "register_operand" "")
9627         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9628    (use (match_operand:V4SF 2 "" ""))
9629    (clobber (reg:CC FLAGS_REG))]
9630   "reload_completed"
9631   [(parallel [(set (match_dup 0) (match_dup 1))
9632               (clobber (reg:CC FLAGS_REG))])]
9634   rtx tmp;
9635   operands[0] = gen_lowpart (SImode, operands[0]);
9636   if (GET_CODE (operands[1]) == ABS)
9637     {
9638       tmp = gen_int_mode (0x7fffffff, SImode);
9639       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9640     }
9641   else
9642     {
9643       tmp = gen_int_mode (0x80000000, SImode);
9644       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9645     }
9646   operands[1] = tmp;
9649 (define_split
9650   [(set (match_operand:DF 0 "register_operand" "")
9651         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9652    (use (match_operand 2 "" ""))
9653    (clobber (reg:CC FLAGS_REG))]
9654   "reload_completed"
9655   [(parallel [(set (match_dup 0) (match_dup 1))
9656               (clobber (reg:CC FLAGS_REG))])]
9658   rtx tmp;
9659   if (TARGET_64BIT)
9660     {
9661       tmp = gen_lowpart (DImode, operands[0]);
9662       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9663       operands[0] = tmp;
9665       if (GET_CODE (operands[1]) == ABS)
9666         tmp = const0_rtx;
9667       else
9668         tmp = gen_rtx_NOT (DImode, tmp);
9669     }
9670   else
9671     {
9672       operands[0] = gen_highpart (SImode, operands[0]);
9673       if (GET_CODE (operands[1]) == ABS)
9674         {
9675           tmp = gen_int_mode (0x7fffffff, SImode);
9676           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9677         }
9678       else
9679         {
9680           tmp = gen_int_mode (0x80000000, SImode);
9681           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9682         }
9683     }
9684   operands[1] = tmp;
9687 (define_split
9688   [(set (match_operand:XF 0 "register_operand" "")
9689         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9690    (use (match_operand 2 "" ""))
9691    (clobber (reg:CC FLAGS_REG))]
9692   "reload_completed"
9693   [(parallel [(set (match_dup 0) (match_dup 1))
9694               (clobber (reg:CC FLAGS_REG))])]
9696   rtx tmp;
9697   operands[0] = gen_rtx_REG (SImode,
9698                              true_regnum (operands[0])
9699                              + (TARGET_64BIT ? 1 : 2));
9700   if (GET_CODE (operands[1]) == ABS)
9701     {
9702       tmp = GEN_INT (0x7fff);
9703       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9704     }
9705   else
9706     {
9707       tmp = GEN_INT (0x8000);
9708       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9709     }
9710   operands[1] = tmp;
9713 (define_split
9714   [(set (match_operand 0 "memory_operand" "")
9715         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9716    (use (match_operand 2 "" ""))
9717    (clobber (reg:CC FLAGS_REG))]
9718   "reload_completed"
9719   [(parallel [(set (match_dup 0) (match_dup 1))
9720               (clobber (reg:CC FLAGS_REG))])]
9722   enum machine_mode mode = GET_MODE (operands[0]);
9723   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9724   rtx tmp;
9726   operands[0] = adjust_address (operands[0], QImode, size - 1);
9727   if (GET_CODE (operands[1]) == ABS)
9728     {
9729       tmp = gen_int_mode (0x7f, QImode);
9730       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9731     }
9732   else
9733     {
9734       tmp = gen_int_mode (0x80, QImode);
9735       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9736     }
9737   operands[1] = tmp;
9740 ;; Conditionalize these after reload. If they match before reload, we 
9741 ;; lose the clobber and ability to use integer instructions.
9743 (define_insn "*negsf2_1"
9744   [(set (match_operand:SF 0 "register_operand" "=f")
9745         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9746   "TARGET_80387 && reload_completed"
9747   "fchs"
9748   [(set_attr "type" "fsgn")
9749    (set_attr "mode" "SF")])
9751 (define_insn "*negdf2_1"
9752   [(set (match_operand:DF 0 "register_operand" "=f")
9753         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9754   "TARGET_80387 && reload_completed"
9755   "fchs"
9756   [(set_attr "type" "fsgn")
9757    (set_attr "mode" "DF")])
9759 (define_insn "*negxf2_1"
9760   [(set (match_operand:XF 0 "register_operand" "=f")
9761         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9762   "TARGET_80387 && reload_completed"
9763   "fchs"
9764   [(set_attr "type" "fsgn")
9765    (set_attr "mode" "XF")])
9767 (define_insn "*abssf2_1"
9768   [(set (match_operand:SF 0 "register_operand" "=f")
9769         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9770   "TARGET_80387 && reload_completed"
9771   "fabs"
9772   [(set_attr "type" "fsgn")
9773    (set_attr "mode" "SF")])
9775 (define_insn "*absdf2_1"
9776   [(set (match_operand:DF 0 "register_operand" "=f")
9777         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9778   "TARGET_80387 && reload_completed"
9779   "fabs"
9780   [(set_attr "type" "fsgn")
9781    (set_attr "mode" "DF")])
9783 (define_insn "*absxf2_1"
9784   [(set (match_operand:XF 0 "register_operand" "=f")
9785         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9786   "TARGET_80387 && reload_completed"
9787   "fabs"
9788   [(set_attr "type" "fsgn")
9789    (set_attr "mode" "DF")])
9791 (define_insn "*negextendsfdf2"
9792   [(set (match_operand:DF 0 "register_operand" "=f")
9793         (neg:DF (float_extend:DF
9794                   (match_operand:SF 1 "register_operand" "0"))))]
9795   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9796   "fchs"
9797   [(set_attr "type" "fsgn")
9798    (set_attr "mode" "DF")])
9800 (define_insn "*negextenddfxf2"
9801   [(set (match_operand:XF 0 "register_operand" "=f")
9802         (neg:XF (float_extend:XF
9803                   (match_operand:DF 1 "register_operand" "0"))))]
9804   "TARGET_80387"
9805   "fchs"
9806   [(set_attr "type" "fsgn")
9807    (set_attr "mode" "XF")])
9809 (define_insn "*negextendsfxf2"
9810   [(set (match_operand:XF 0 "register_operand" "=f")
9811         (neg:XF (float_extend:XF
9812                   (match_operand:SF 1 "register_operand" "0"))))]
9813   "TARGET_80387"
9814   "fchs"
9815   [(set_attr "type" "fsgn")
9816    (set_attr "mode" "XF")])
9818 (define_insn "*absextendsfdf2"
9819   [(set (match_operand:DF 0 "register_operand" "=f")
9820         (abs:DF (float_extend:DF
9821                   (match_operand:SF 1 "register_operand" "0"))))]
9822   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9823   "fabs"
9824   [(set_attr "type" "fsgn")
9825    (set_attr "mode" "DF")])
9827 (define_insn "*absextenddfxf2"
9828   [(set (match_operand:XF 0 "register_operand" "=f")
9829         (abs:XF (float_extend:XF
9830           (match_operand:DF 1 "register_operand" "0"))))]
9831   "TARGET_80387"
9832   "fabs"
9833   [(set_attr "type" "fsgn")
9834    (set_attr "mode" "XF")])
9836 (define_insn "*absextendsfxf2"
9837   [(set (match_operand:XF 0 "register_operand" "=f")
9838         (abs:XF (float_extend:XF
9839           (match_operand:SF 1 "register_operand" "0"))))]
9840   "TARGET_80387"
9841   "fabs"
9842   [(set_attr "type" "fsgn")
9843    (set_attr "mode" "XF")])
9845 ;; One complement instructions
9847 (define_expand "one_cmpldi2"
9848   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9849         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9850   "TARGET_64BIT"
9851   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9853 (define_insn "*one_cmpldi2_1_rex64"
9854   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9855         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9856   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9857   "not{q}\t%0"
9858   [(set_attr "type" "negnot")
9859    (set_attr "mode" "DI")])
9861 (define_insn "*one_cmpldi2_2_rex64"
9862   [(set (reg FLAGS_REG)
9863         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9864                  (const_int 0)))
9865    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9866         (not:DI (match_dup 1)))]
9867   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9868    && ix86_unary_operator_ok (NOT, DImode, operands)"
9869   "#"
9870   [(set_attr "type" "alu1")
9871    (set_attr "mode" "DI")])
9873 (define_split
9874   [(set (match_operand 0 "flags_reg_operand" "")
9875         (match_operator 2 "compare_operator"
9876           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9877            (const_int 0)]))
9878    (set (match_operand:DI 1 "nonimmediate_operand" "")
9879         (not:DI (match_dup 3)))]
9880   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9881   [(parallel [(set (match_dup 0)
9882                    (match_op_dup 2
9883                      [(xor:DI (match_dup 3) (const_int -1))
9884                       (const_int 0)]))
9885               (set (match_dup 1)
9886                    (xor:DI (match_dup 3) (const_int -1)))])]
9887   "")
9889 (define_expand "one_cmplsi2"
9890   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9891         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9892   ""
9893   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9895 (define_insn "*one_cmplsi2_1"
9896   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9897         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9898   "ix86_unary_operator_ok (NOT, SImode, operands)"
9899   "not{l}\t%0"
9900   [(set_attr "type" "negnot")
9901    (set_attr "mode" "SI")])
9903 ;; ??? Currently never generated - xor is used instead.
9904 (define_insn "*one_cmplsi2_1_zext"
9905   [(set (match_operand:DI 0 "register_operand" "=r")
9906         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9907   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9908   "not{l}\t%k0"
9909   [(set_attr "type" "negnot")
9910    (set_attr "mode" "SI")])
9912 (define_insn "*one_cmplsi2_2"
9913   [(set (reg FLAGS_REG)
9914         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9915                  (const_int 0)))
9916    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9917         (not:SI (match_dup 1)))]
9918   "ix86_match_ccmode (insn, CCNOmode)
9919    && ix86_unary_operator_ok (NOT, SImode, operands)"
9920   "#"
9921   [(set_attr "type" "alu1")
9922    (set_attr "mode" "SI")])
9924 (define_split
9925   [(set (match_operand 0 "flags_reg_operand" "")
9926         (match_operator 2 "compare_operator"
9927           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9928            (const_int 0)]))
9929    (set (match_operand:SI 1 "nonimmediate_operand" "")
9930         (not:SI (match_dup 3)))]
9931   "ix86_match_ccmode (insn, CCNOmode)"
9932   [(parallel [(set (match_dup 0)
9933                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9934                                     (const_int 0)]))
9935               (set (match_dup 1)
9936                    (xor:SI (match_dup 3) (const_int -1)))])]
9937   "")
9939 ;; ??? Currently never generated - xor is used instead.
9940 (define_insn "*one_cmplsi2_2_zext"
9941   [(set (reg FLAGS_REG)
9942         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9943                  (const_int 0)))
9944    (set (match_operand:DI 0 "register_operand" "=r")
9945         (zero_extend:DI (not:SI (match_dup 1))))]
9946   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9947    && ix86_unary_operator_ok (NOT, SImode, operands)"
9948   "#"
9949   [(set_attr "type" "alu1")
9950    (set_attr "mode" "SI")])
9952 (define_split
9953   [(set (match_operand 0 "flags_reg_operand" "")
9954         (match_operator 2 "compare_operator"
9955           [(not:SI (match_operand:SI 3 "register_operand" ""))
9956            (const_int 0)]))
9957    (set (match_operand:DI 1 "register_operand" "")
9958         (zero_extend:DI (not:SI (match_dup 3))))]
9959   "ix86_match_ccmode (insn, CCNOmode)"
9960   [(parallel [(set (match_dup 0)
9961                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9962                                     (const_int 0)]))
9963               (set (match_dup 1)
9964                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9965   "")
9967 (define_expand "one_cmplhi2"
9968   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9969         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9970   "TARGET_HIMODE_MATH"
9971   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9973 (define_insn "*one_cmplhi2_1"
9974   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9975         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9976   "ix86_unary_operator_ok (NOT, HImode, operands)"
9977   "not{w}\t%0"
9978   [(set_attr "type" "negnot")
9979    (set_attr "mode" "HI")])
9981 (define_insn "*one_cmplhi2_2"
9982   [(set (reg FLAGS_REG)
9983         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9984                  (const_int 0)))
9985    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9986         (not:HI (match_dup 1)))]
9987   "ix86_match_ccmode (insn, CCNOmode)
9988    && ix86_unary_operator_ok (NEG, HImode, operands)"
9989   "#"
9990   [(set_attr "type" "alu1")
9991    (set_attr "mode" "HI")])
9993 (define_split
9994   [(set (match_operand 0 "flags_reg_operand" "")
9995         (match_operator 2 "compare_operator"
9996           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9997            (const_int 0)]))
9998    (set (match_operand:HI 1 "nonimmediate_operand" "")
9999         (not:HI (match_dup 3)))]
10000   "ix86_match_ccmode (insn, CCNOmode)"
10001   [(parallel [(set (match_dup 0)
10002                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10003                                     (const_int 0)]))
10004               (set (match_dup 1)
10005                    (xor:HI (match_dup 3) (const_int -1)))])]
10006   "")
10008 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10009 (define_expand "one_cmplqi2"
10010   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10011         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10012   "TARGET_QIMODE_MATH"
10013   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10015 (define_insn "*one_cmplqi2_1"
10016   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10017         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10018   "ix86_unary_operator_ok (NOT, QImode, operands)"
10019   "@
10020    not{b}\t%0
10021    not{l}\t%k0"
10022   [(set_attr "type" "negnot")
10023    (set_attr "mode" "QI,SI")])
10025 (define_insn "*one_cmplqi2_2"
10026   [(set (reg FLAGS_REG)
10027         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10028                  (const_int 0)))
10029    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10030         (not:QI (match_dup 1)))]
10031   "ix86_match_ccmode (insn, CCNOmode)
10032    && ix86_unary_operator_ok (NOT, QImode, operands)"
10033   "#"
10034   [(set_attr "type" "alu1")
10035    (set_attr "mode" "QI")])
10037 (define_split
10038   [(set (match_operand 0 "flags_reg_operand" "")
10039         (match_operator 2 "compare_operator"
10040           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10041            (const_int 0)]))
10042    (set (match_operand:QI 1 "nonimmediate_operand" "")
10043         (not:QI (match_dup 3)))]
10044   "ix86_match_ccmode (insn, CCNOmode)"
10045   [(parallel [(set (match_dup 0)
10046                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10047                                     (const_int 0)]))
10048               (set (match_dup 1)
10049                    (xor:QI (match_dup 3) (const_int -1)))])]
10050   "")
10052 ;; Arithmetic shift instructions
10054 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10055 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10056 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10057 ;; from the assembler input.
10059 ;; This instruction shifts the target reg/mem as usual, but instead of
10060 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10061 ;; is a left shift double, bits are taken from the high order bits of
10062 ;; reg, else if the insn is a shift right double, bits are taken from the
10063 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10064 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10066 ;; Since sh[lr]d does not change the `reg' operand, that is done
10067 ;; separately, making all shifts emit pairs of shift double and normal
10068 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10069 ;; support a 63 bit shift, each shift where the count is in a reg expands
10070 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10072 ;; If the shift count is a constant, we need never emit more than one
10073 ;; shift pair, instead using moves and sign extension for counts greater
10074 ;; than 31.
10076 (define_expand "ashldi3"
10077   [(set (match_operand:DI 0 "shiftdi_operand" "")
10078         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10079                    (match_operand:QI 2 "nonmemory_operand" "")))]
10080   ""
10081   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10083 (define_insn "*ashldi3_1_rex64"
10084   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10085         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10086                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10087    (clobber (reg:CC FLAGS_REG))]
10088   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10090   switch (get_attr_type (insn))
10091     {
10092     case TYPE_ALU:
10093       gcc_assert (operands[2] == const1_rtx);
10094       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10095       return "add{q}\t{%0, %0|%0, %0}";
10097     case TYPE_LEA:
10098       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10099       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10100       operands[1] = gen_rtx_MULT (DImode, operands[1],
10101                                   GEN_INT (1 << INTVAL (operands[2])));
10102       return "lea{q}\t{%a1, %0|%0, %a1}";
10104     default:
10105       if (REG_P (operands[2]))
10106         return "sal{q}\t{%b2, %0|%0, %b2}";
10107       else if (operands[2] == const1_rtx
10108                && (TARGET_SHIFT1 || optimize_size))
10109         return "sal{q}\t%0";
10110       else
10111         return "sal{q}\t{%2, %0|%0, %2}";
10112     }
10114   [(set (attr "type")
10115      (cond [(eq_attr "alternative" "1")
10116               (const_string "lea")
10117             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10118                           (const_int 0))
10119                       (match_operand 0 "register_operand" ""))
10120                  (match_operand 2 "const1_operand" ""))
10121               (const_string "alu")
10122            ]
10123            (const_string "ishift")))
10124    (set_attr "mode" "DI")])
10126 ;; Convert lea to the lea pattern to avoid flags dependency.
10127 (define_split
10128   [(set (match_operand:DI 0 "register_operand" "")
10129         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10130                    (match_operand:QI 2 "immediate_operand" "")))
10131    (clobber (reg:CC FLAGS_REG))]
10132   "TARGET_64BIT && reload_completed
10133    && true_regnum (operands[0]) != true_regnum (operands[1])"
10134   [(set (match_dup 0)
10135         (mult:DI (match_dup 1)
10136                  (match_dup 2)))]
10137   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10139 ;; This pattern can't accept a variable shift count, since shifts by
10140 ;; zero don't affect the flags.  We assume that shifts by constant
10141 ;; zero are optimized away.
10142 (define_insn "*ashldi3_cmp_rex64"
10143   [(set (reg FLAGS_REG)
10144         (compare
10145           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10146                      (match_operand:QI 2 "immediate_operand" "e"))
10147           (const_int 0)))
10148    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10149         (ashift:DI (match_dup 1) (match_dup 2)))]
10150   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10151    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10153   switch (get_attr_type (insn))
10154     {
10155     case TYPE_ALU:
10156       gcc_assert (operands[2] == const1_rtx);
10157       return "add{q}\t{%0, %0|%0, %0}";
10159     default:
10160       if (REG_P (operands[2]))
10161         return "sal{q}\t{%b2, %0|%0, %b2}";
10162       else if (operands[2] == const1_rtx
10163                && (TARGET_SHIFT1 || optimize_size))
10164         return "sal{q}\t%0";
10165       else
10166         return "sal{q}\t{%2, %0|%0, %2}";
10167     }
10169   [(set (attr "type")
10170      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10171                           (const_int 0))
10172                       (match_operand 0 "register_operand" ""))
10173                  (match_operand 2 "const1_operand" ""))
10174               (const_string "alu")
10175            ]
10176            (const_string "ishift")))
10177    (set_attr "mode" "DI")])
10179 (define_insn "*ashldi3_1"
10180   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10181         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10182                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10183    (clobber (reg:CC FLAGS_REG))]
10184   "!TARGET_64BIT"
10185   "#"
10186   [(set_attr "type" "multi")])
10188 ;; By default we don't ask for a scratch register, because when DImode
10189 ;; values are manipulated, registers are already at a premium.  But if
10190 ;; we have one handy, we won't turn it away.
10191 (define_peephole2
10192   [(match_scratch:SI 3 "r")
10193    (parallel [(set (match_operand:DI 0 "register_operand" "")
10194                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10195                               (match_operand:QI 2 "nonmemory_operand" "")))
10196               (clobber (reg:CC FLAGS_REG))])
10197    (match_dup 3)]
10198   "!TARGET_64BIT && TARGET_CMOVE"
10199   [(const_int 0)]
10200   "ix86_split_ashldi (operands, operands[3]); DONE;")
10202 (define_split
10203   [(set (match_operand:DI 0 "register_operand" "")
10204         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10205                    (match_operand:QI 2 "nonmemory_operand" "")))
10206    (clobber (reg:CC FLAGS_REG))]
10207   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10208   [(const_int 0)]
10209   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10211 (define_insn "x86_shld_1"
10212   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10213         (ior:SI (ashift:SI (match_dup 0)
10214                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10215                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10216                   (minus:QI (const_int 32) (match_dup 2)))))
10217    (clobber (reg:CC FLAGS_REG))]
10218   ""
10219   "@
10220    shld{l}\t{%2, %1, %0|%0, %1, %2}
10221    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10222   [(set_attr "type" "ishift")
10223    (set_attr "prefix_0f" "1")
10224    (set_attr "mode" "SI")
10225    (set_attr "pent_pair" "np")
10226    (set_attr "athlon_decode" "vector")])
10228 (define_expand "x86_shift_adj_1"
10229   [(set (reg:CCZ FLAGS_REG)
10230         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10231                              (const_int 32))
10232                      (const_int 0)))
10233    (set (match_operand:SI 0 "register_operand" "")
10234         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10235                          (match_operand:SI 1 "register_operand" "")
10236                          (match_dup 0)))
10237    (set (match_dup 1)
10238         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10239                          (match_operand:SI 3 "register_operand" "r")
10240                          (match_dup 1)))]
10241   "TARGET_CMOVE"
10242   "")
10244 (define_expand "x86_shift_adj_2"
10245   [(use (match_operand:SI 0 "register_operand" ""))
10246    (use (match_operand:SI 1 "register_operand" ""))
10247    (use (match_operand:QI 2 "register_operand" ""))]
10248   ""
10250   rtx label = gen_label_rtx ();
10251   rtx tmp;
10253   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10255   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10256   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10257   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10258                               gen_rtx_LABEL_REF (VOIDmode, label),
10259                               pc_rtx);
10260   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10261   JUMP_LABEL (tmp) = label;
10263   emit_move_insn (operands[0], operands[1]);
10264   ix86_expand_clear (operands[1]);
10266   emit_label (label);
10267   LABEL_NUSES (label) = 1;
10269   DONE;
10272 (define_expand "ashlsi3"
10273   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10274         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10275                    (match_operand:QI 2 "nonmemory_operand" "")))
10276    (clobber (reg:CC FLAGS_REG))]
10277   ""
10278   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10280 (define_insn "*ashlsi3_1"
10281   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10282         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10283                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10284    (clobber (reg:CC FLAGS_REG))]
10285   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10287   switch (get_attr_type (insn))
10288     {
10289     case TYPE_ALU:
10290       gcc_assert (operands[2] == const1_rtx);
10291       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10292       return "add{l}\t{%0, %0|%0, %0}";
10294     case TYPE_LEA:
10295       return "#";
10297     default:
10298       if (REG_P (operands[2]))
10299         return "sal{l}\t{%b2, %0|%0, %b2}";
10300       else if (operands[2] == const1_rtx
10301                && (TARGET_SHIFT1 || optimize_size))
10302         return "sal{l}\t%0";
10303       else
10304         return "sal{l}\t{%2, %0|%0, %2}";
10305     }
10307   [(set (attr "type")
10308      (cond [(eq_attr "alternative" "1")
10309               (const_string "lea")
10310             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10311                           (const_int 0))
10312                       (match_operand 0 "register_operand" ""))
10313                  (match_operand 2 "const1_operand" ""))
10314               (const_string "alu")
10315            ]
10316            (const_string "ishift")))
10317    (set_attr "mode" "SI")])
10319 ;; Convert lea to the lea pattern to avoid flags dependency.
10320 (define_split
10321   [(set (match_operand 0 "register_operand" "")
10322         (ashift (match_operand 1 "index_register_operand" "")
10323                 (match_operand:QI 2 "const_int_operand" "")))
10324    (clobber (reg:CC FLAGS_REG))]
10325   "reload_completed
10326    && true_regnum (operands[0]) != true_regnum (operands[1])
10327    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10328   [(const_int 0)]
10330   rtx pat;
10331   enum machine_mode mode = GET_MODE (operands[0]);
10333   if (GET_MODE_SIZE (mode) < 4)
10334     operands[0] = gen_lowpart (SImode, operands[0]);
10335   if (mode != Pmode)
10336     operands[1] = gen_lowpart (Pmode, operands[1]);
10337   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10339   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10340   if (Pmode != SImode)
10341     pat = gen_rtx_SUBREG (SImode, pat, 0);
10342   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10343   DONE;
10346 ;; Rare case of shifting RSP is handled by generating move and shift
10347 (define_split
10348   [(set (match_operand 0 "register_operand" "")
10349         (ashift (match_operand 1 "register_operand" "")
10350                 (match_operand:QI 2 "const_int_operand" "")))
10351    (clobber (reg:CC FLAGS_REG))]
10352   "reload_completed
10353    && true_regnum (operands[0]) != true_regnum (operands[1])"
10354   [(const_int 0)]
10356   rtx pat, clob;
10357   emit_move_insn (operands[1], operands[0]);
10358   pat = gen_rtx_SET (VOIDmode, operands[0],
10359                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10360                                      operands[0], operands[2]));
10361   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10362   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10363   DONE;
10366 (define_insn "*ashlsi3_1_zext"
10367   [(set (match_operand:DI 0 "register_operand" "=r,r")
10368         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10369                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10370    (clobber (reg:CC FLAGS_REG))]
10371   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10373   switch (get_attr_type (insn))
10374     {
10375     case TYPE_ALU:
10376       gcc_assert (operands[2] == const1_rtx);
10377       return "add{l}\t{%k0, %k0|%k0, %k0}";
10379     case TYPE_LEA:
10380       return "#";
10382     default:
10383       if (REG_P (operands[2]))
10384         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10385       else if (operands[2] == const1_rtx
10386                && (TARGET_SHIFT1 || optimize_size))
10387         return "sal{l}\t%k0";
10388       else
10389         return "sal{l}\t{%2, %k0|%k0, %2}";
10390     }
10392   [(set (attr "type")
10393      (cond [(eq_attr "alternative" "1")
10394               (const_string "lea")
10395             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10396                      (const_int 0))
10397                  (match_operand 2 "const1_operand" ""))
10398               (const_string "alu")
10399            ]
10400            (const_string "ishift")))
10401    (set_attr "mode" "SI")])
10403 ;; Convert lea to the lea pattern to avoid flags dependency.
10404 (define_split
10405   [(set (match_operand:DI 0 "register_operand" "")
10406         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10407                                 (match_operand:QI 2 "const_int_operand" ""))))
10408    (clobber (reg:CC FLAGS_REG))]
10409   "TARGET_64BIT && reload_completed
10410    && true_regnum (operands[0]) != true_regnum (operands[1])"
10411   [(set (match_dup 0) (zero_extend:DI
10412                         (subreg:SI (mult:SI (match_dup 1)
10413                                             (match_dup 2)) 0)))]
10415   operands[1] = gen_lowpart (Pmode, operands[1]);
10416   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10419 ;; This pattern can't accept a variable shift count, since shifts by
10420 ;; zero don't affect the flags.  We assume that shifts by constant
10421 ;; zero are optimized away.
10422 (define_insn "*ashlsi3_cmp"
10423   [(set (reg FLAGS_REG)
10424         (compare
10425           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10426                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10427           (const_int 0)))
10428    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10429         (ashift:SI (match_dup 1) (match_dup 2)))]
10430   "ix86_match_ccmode (insn, CCGOCmode)
10431    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10433   switch (get_attr_type (insn))
10434     {
10435     case TYPE_ALU:
10436       gcc_assert (operands[2] == const1_rtx);
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       gcc_assert (operands[2] == const1_rtx);
10474       return "add{l}\t{%k0, %k0|%k0, %k0}";
10476     default:
10477       if (REG_P (operands[2]))
10478         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10479       else if (operands[2] == const1_rtx
10480                && (TARGET_SHIFT1 || optimize_size))
10481         return "sal{l}\t%k0";
10482       else
10483         return "sal{l}\t{%2, %k0|%k0, %2}";
10484     }
10486   [(set (attr "type")
10487      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10488                      (const_int 0))
10489                  (match_operand 2 "const1_operand" ""))
10490               (const_string "alu")
10491            ]
10492            (const_string "ishift")))
10493    (set_attr "mode" "SI")])
10495 (define_expand "ashlhi3"
10496   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10497         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10498                    (match_operand:QI 2 "nonmemory_operand" "")))
10499    (clobber (reg:CC FLAGS_REG))]
10500   "TARGET_HIMODE_MATH"
10501   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10503 (define_insn "*ashlhi3_1_lea"
10504   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10505         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10506                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10507    (clobber (reg:CC FLAGS_REG))]
10508   "!TARGET_PARTIAL_REG_STALL
10509    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10511   switch (get_attr_type (insn))
10512     {
10513     case TYPE_LEA:
10514       return "#";
10515     case TYPE_ALU:
10516       gcc_assert (operands[2] == const1_rtx);
10517       return "add{w}\t{%0, %0|%0, %0}";
10519     default:
10520       if (REG_P (operands[2]))
10521         return "sal{w}\t{%b2, %0|%0, %b2}";
10522       else if (operands[2] == const1_rtx
10523                && (TARGET_SHIFT1 || optimize_size))
10524         return "sal{w}\t%0";
10525       else
10526         return "sal{w}\t{%2, %0|%0, %2}";
10527     }
10529   [(set (attr "type")
10530      (cond [(eq_attr "alternative" "1")
10531               (const_string "lea")
10532             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10533                           (const_int 0))
10534                       (match_operand 0 "register_operand" ""))
10535                  (match_operand 2 "const1_operand" ""))
10536               (const_string "alu")
10537            ]
10538            (const_string "ishift")))
10539    (set_attr "mode" "HI,SI")])
10541 (define_insn "*ashlhi3_1"
10542   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10543         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10544                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10545    (clobber (reg:CC FLAGS_REG))]
10546   "TARGET_PARTIAL_REG_STALL
10547    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10549   switch (get_attr_type (insn))
10550     {
10551     case TYPE_ALU:
10552       gcc_assert (operands[2] == const1_rtx);
10553       return "add{w}\t{%0, %0|%0, %0}";
10555     default:
10556       if (REG_P (operands[2]))
10557         return "sal{w}\t{%b2, %0|%0, %b2}";
10558       else if (operands[2] == const1_rtx
10559                && (TARGET_SHIFT1 || optimize_size))
10560         return "sal{w}\t%0";
10561       else
10562         return "sal{w}\t{%2, %0|%0, %2}";
10563     }
10565   [(set (attr "type")
10566      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10567                           (const_int 0))
10568                       (match_operand 0 "register_operand" ""))
10569                  (match_operand 2 "const1_operand" ""))
10570               (const_string "alu")
10571            ]
10572            (const_string "ishift")))
10573    (set_attr "mode" "HI")])
10575 ;; This pattern can't accept a variable shift count, since shifts by
10576 ;; zero don't affect the flags.  We assume that shifts by constant
10577 ;; zero are optimized away.
10578 (define_insn "*ashlhi3_cmp"
10579   [(set (reg FLAGS_REG)
10580         (compare
10581           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10582                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10583           (const_int 0)))
10584    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10585         (ashift:HI (match_dup 1) (match_dup 2)))]
10586   "ix86_match_ccmode (insn, CCGOCmode)
10587    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10589   switch (get_attr_type (insn))
10590     {
10591     case TYPE_ALU:
10592       gcc_assert (operands[2] == const1_rtx);
10593       return "add{w}\t{%0, %0|%0, %0}";
10595     default:
10596       if (REG_P (operands[2]))
10597         return "sal{w}\t{%b2, %0|%0, %b2}";
10598       else if (operands[2] == const1_rtx
10599                && (TARGET_SHIFT1 || optimize_size))
10600         return "sal{w}\t%0";
10601       else
10602         return "sal{w}\t{%2, %0|%0, %2}";
10603     }
10605   [(set (attr "type")
10606      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10607                           (const_int 0))
10608                       (match_operand 0 "register_operand" ""))
10609                  (match_operand 2 "const1_operand" ""))
10610               (const_string "alu")
10611            ]
10612            (const_string "ishift")))
10613    (set_attr "mode" "HI")])
10615 (define_expand "ashlqi3"
10616   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10617         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10618                    (match_operand:QI 2 "nonmemory_operand" "")))
10619    (clobber (reg:CC FLAGS_REG))]
10620   "TARGET_QIMODE_MATH"
10621   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10623 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10625 (define_insn "*ashlqi3_1_lea"
10626   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10627         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10628                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10629    (clobber (reg:CC FLAGS_REG))]
10630   "!TARGET_PARTIAL_REG_STALL
10631    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10633   switch (get_attr_type (insn))
10634     {
10635     case TYPE_LEA:
10636       return "#";
10637     case TYPE_ALU:
10638       gcc_assert (operands[2] == const1_rtx);
10639       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10640         return "add{l}\t{%k0, %k0|%k0, %k0}";
10641       else
10642         return "add{b}\t{%0, %0|%0, %0}";
10644     default:
10645       if (REG_P (operands[2]))
10646         {
10647           if (get_attr_mode (insn) == MODE_SI)
10648             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10649           else
10650             return "sal{b}\t{%b2, %0|%0, %b2}";
10651         }
10652       else if (operands[2] == const1_rtx
10653                && (TARGET_SHIFT1 || optimize_size))
10654         {
10655           if (get_attr_mode (insn) == MODE_SI)
10656             return "sal{l}\t%0";
10657           else
10658             return "sal{b}\t%0";
10659         }
10660       else
10661         {
10662           if (get_attr_mode (insn) == MODE_SI)
10663             return "sal{l}\t{%2, %k0|%k0, %2}";
10664           else
10665             return "sal{b}\t{%2, %0|%0, %2}";
10666         }
10667     }
10669   [(set (attr "type")
10670      (cond [(eq_attr "alternative" "2")
10671               (const_string "lea")
10672             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10673                           (const_int 0))
10674                       (match_operand 0 "register_operand" ""))
10675                  (match_operand 2 "const1_operand" ""))
10676               (const_string "alu")
10677            ]
10678            (const_string "ishift")))
10679    (set_attr "mode" "QI,SI,SI")])
10681 (define_insn "*ashlqi3_1"
10682   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10683         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10684                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10685    (clobber (reg:CC FLAGS_REG))]
10686   "TARGET_PARTIAL_REG_STALL
10687    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10689   switch (get_attr_type (insn))
10690     {
10691     case TYPE_ALU:
10692       gcc_assert (operands[2] == const1_rtx);
10693       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10694         return "add{l}\t{%k0, %k0|%k0, %k0}";
10695       else
10696         return "add{b}\t{%0, %0|%0, %0}";
10698     default:
10699       if (REG_P (operands[2]))
10700         {
10701           if (get_attr_mode (insn) == MODE_SI)
10702             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10703           else
10704             return "sal{b}\t{%b2, %0|%0, %b2}";
10705         }
10706       else if (operands[2] == const1_rtx
10707                && (TARGET_SHIFT1 || optimize_size))
10708         {
10709           if (get_attr_mode (insn) == MODE_SI)
10710             return "sal{l}\t%0";
10711           else
10712             return "sal{b}\t%0";
10713         }
10714       else
10715         {
10716           if (get_attr_mode (insn) == MODE_SI)
10717             return "sal{l}\t{%2, %k0|%k0, %2}";
10718           else
10719             return "sal{b}\t{%2, %0|%0, %2}";
10720         }
10721     }
10723   [(set (attr "type")
10724      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10725                           (const_int 0))
10726                       (match_operand 0 "register_operand" ""))
10727                  (match_operand 2 "const1_operand" ""))
10728               (const_string "alu")
10729            ]
10730            (const_string "ishift")))
10731    (set_attr "mode" "QI,SI")])
10733 ;; This pattern can't accept a variable shift count, since shifts by
10734 ;; zero don't affect the flags.  We assume that shifts by constant
10735 ;; zero are optimized away.
10736 (define_insn "*ashlqi3_cmp"
10737   [(set (reg FLAGS_REG)
10738         (compare
10739           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10740                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10741           (const_int 0)))
10742    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10743         (ashift:QI (match_dup 1) (match_dup 2)))]
10744   "ix86_match_ccmode (insn, CCGOCmode)
10745    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10747   switch (get_attr_type (insn))
10748     {
10749     case TYPE_ALU:
10750       gcc_assert (operands[2] == const1_rtx);
10751       return "add{b}\t{%0, %0|%0, %0}";
10753     default:
10754       if (REG_P (operands[2]))
10755         return "sal{b}\t{%b2, %0|%0, %b2}";
10756       else if (operands[2] == const1_rtx
10757                && (TARGET_SHIFT1 || optimize_size))
10758         return "sal{b}\t%0";
10759       else
10760         return "sal{b}\t{%2, %0|%0, %2}";
10761     }
10763   [(set (attr "type")
10764      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10765                           (const_int 0))
10766                       (match_operand 0 "register_operand" ""))
10767                  (match_operand 2 "const1_operand" ""))
10768               (const_string "alu")
10769            ]
10770            (const_string "ishift")))
10771    (set_attr "mode" "QI")])
10773 ;; See comment above `ashldi3' about how this works.
10775 (define_expand "ashrdi3"
10776   [(set (match_operand:DI 0 "shiftdi_operand" "")
10777         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10778                      (match_operand:QI 2 "nonmemory_operand" "")))]
10779   ""
10780   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10782 (define_insn "*ashrdi3_63_rex64"
10783   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10784         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10785                      (match_operand:DI 2 "const_int_operand" "i,i")))
10786    (clobber (reg:CC FLAGS_REG))]
10787   "TARGET_64BIT && INTVAL (operands[2]) == 63
10788    && (TARGET_USE_CLTD || optimize_size)
10789    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10790   "@
10791    {cqto|cqo}
10792    sar{q}\t{%2, %0|%0, %2}"
10793   [(set_attr "type" "imovx,ishift")
10794    (set_attr "prefix_0f" "0,*")
10795    (set_attr "length_immediate" "0,*")
10796    (set_attr "modrm" "0,1")
10797    (set_attr "mode" "DI")])
10799 (define_insn "*ashrdi3_1_one_bit_rex64"
10800   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10801         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10802                      (match_operand:QI 2 "const1_operand" "")))
10803    (clobber (reg:CC FLAGS_REG))]
10804   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10805    && (TARGET_SHIFT1 || optimize_size)"
10806   "sar{q}\t%0"
10807   [(set_attr "type" "ishift")
10808    (set (attr "length") 
10809      (if_then_else (match_operand:DI 0 "register_operand" "") 
10810         (const_string "2")
10811         (const_string "*")))])
10813 (define_insn "*ashrdi3_1_rex64"
10814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10815         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10816                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10817    (clobber (reg:CC FLAGS_REG))]
10818   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10819   "@
10820    sar{q}\t{%2, %0|%0, %2}
10821    sar{q}\t{%b2, %0|%0, %b2}"
10822   [(set_attr "type" "ishift")
10823    (set_attr "mode" "DI")])
10825 ;; This pattern can't accept a variable shift count, since shifts by
10826 ;; zero don't affect the flags.  We assume that shifts by constant
10827 ;; zero are optimized away.
10828 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10829   [(set (reg FLAGS_REG)
10830         (compare
10831           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10832                        (match_operand:QI 2 "const1_operand" ""))
10833           (const_int 0)))
10834    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10835         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10836   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10837    && (TARGET_SHIFT1 || optimize_size)
10838    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10839   "sar{q}\t%0"
10840   [(set_attr "type" "ishift")
10841    (set (attr "length") 
10842      (if_then_else (match_operand:DI 0 "register_operand" "") 
10843         (const_string "2")
10844         (const_string "*")))])
10846 ;; This pattern can't accept a variable shift count, since shifts by
10847 ;; zero don't affect the flags.  We assume that shifts by constant
10848 ;; zero are optimized away.
10849 (define_insn "*ashrdi3_cmp_rex64"
10850   [(set (reg FLAGS_REG)
10851         (compare
10852           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10853                        (match_operand:QI 2 "const_int_operand" "n"))
10854           (const_int 0)))
10855    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10856         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10857   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10858    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10859   "sar{q}\t{%2, %0|%0, %2}"
10860   [(set_attr "type" "ishift")
10861    (set_attr "mode" "DI")])
10863 (define_insn "*ashrdi3_1"
10864   [(set (match_operand:DI 0 "register_operand" "=r")
10865         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10866                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
10867    (clobber (reg:CC FLAGS_REG))]
10868   "!TARGET_64BIT"
10869   "#"
10870   [(set_attr "type" "multi")])
10872 ;; By default we don't ask for a scratch register, because when DImode
10873 ;; values are manipulated, registers are already at a premium.  But if
10874 ;; we have one handy, we won't turn it away.
10875 (define_peephole2
10876   [(match_scratch:SI 3 "r")
10877    (parallel [(set (match_operand:DI 0 "register_operand" "")
10878                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10879                                 (match_operand:QI 2 "nonmemory_operand" "")))
10880               (clobber (reg:CC FLAGS_REG))])
10881    (match_dup 3)]
10882   "!TARGET_64BIT && TARGET_CMOVE"
10883   [(const_int 0)]
10884   "ix86_split_ashrdi (operands, operands[3]); DONE;")
10886 (define_split
10887   [(set (match_operand:DI 0 "register_operand" "")
10888         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10889                      (match_operand:QI 2 "nonmemory_operand" "")))
10890    (clobber (reg:CC FLAGS_REG))]
10891   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10892   [(const_int 0)]
10893   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10895 (define_insn "x86_shrd_1"
10896   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10897         (ior:SI (ashiftrt:SI (match_dup 0)
10898                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10899                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10900                   (minus:QI (const_int 32) (match_dup 2)))))
10901    (clobber (reg:CC FLAGS_REG))]
10902   ""
10903   "@
10904    shrd{l}\t{%2, %1, %0|%0, %1, %2}
10905    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10906   [(set_attr "type" "ishift")
10907    (set_attr "prefix_0f" "1")
10908    (set_attr "pent_pair" "np")
10909    (set_attr "mode" "SI")])
10911 (define_expand "x86_shift_adj_3"
10912   [(use (match_operand:SI 0 "register_operand" ""))
10913    (use (match_operand:SI 1 "register_operand" ""))
10914    (use (match_operand:QI 2 "register_operand" ""))]
10915   ""
10917   rtx label = gen_label_rtx ();
10918   rtx tmp;
10920   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10922   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10923   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10924   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10925                               gen_rtx_LABEL_REF (VOIDmode, label),
10926                               pc_rtx);
10927   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10928   JUMP_LABEL (tmp) = label;
10930   emit_move_insn (operands[0], operands[1]);
10931   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10933   emit_label (label);
10934   LABEL_NUSES (label) = 1;
10936   DONE;
10939 (define_insn "ashrsi3_31"
10940   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10941         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10942                      (match_operand:SI 2 "const_int_operand" "i,i")))
10943    (clobber (reg:CC FLAGS_REG))]
10944   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10945    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10946   "@
10947    {cltd|cdq}
10948    sar{l}\t{%2, %0|%0, %2}"
10949   [(set_attr "type" "imovx,ishift")
10950    (set_attr "prefix_0f" "0,*")
10951    (set_attr "length_immediate" "0,*")
10952    (set_attr "modrm" "0,1")
10953    (set_attr "mode" "SI")])
10955 (define_insn "*ashrsi3_31_zext"
10956   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10957         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10958                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
10959    (clobber (reg:CC FLAGS_REG))]
10960   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10961    && INTVAL (operands[2]) == 31
10962    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10963   "@
10964    {cltd|cdq}
10965    sar{l}\t{%2, %k0|%k0, %2}"
10966   [(set_attr "type" "imovx,ishift")
10967    (set_attr "prefix_0f" "0,*")
10968    (set_attr "length_immediate" "0,*")
10969    (set_attr "modrm" "0,1")
10970    (set_attr "mode" "SI")])
10972 (define_expand "ashrsi3"
10973   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10974         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10975                      (match_operand:QI 2 "nonmemory_operand" "")))
10976    (clobber (reg:CC FLAGS_REG))]
10977   ""
10978   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10980 (define_insn "*ashrsi3_1_one_bit"
10981   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10982         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10983                      (match_operand:QI 2 "const1_operand" "")))
10984    (clobber (reg:CC FLAGS_REG))]
10985   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10986    && (TARGET_SHIFT1 || optimize_size)"
10987   "sar{l}\t%0"
10988   [(set_attr "type" "ishift")
10989    (set (attr "length") 
10990      (if_then_else (match_operand:SI 0 "register_operand" "") 
10991         (const_string "2")
10992         (const_string "*")))])
10994 (define_insn "*ashrsi3_1_one_bit_zext"
10995   [(set (match_operand:DI 0 "register_operand" "=r")
10996         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10997                                      (match_operand:QI 2 "const1_operand" ""))))
10998    (clobber (reg:CC FLAGS_REG))]
10999   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11000    && (TARGET_SHIFT1 || optimize_size)"
11001   "sar{l}\t%k0"
11002   [(set_attr "type" "ishift")
11003    (set_attr "length" "2")])
11005 (define_insn "*ashrsi3_1"
11006   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11007         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11008                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11009    (clobber (reg:CC FLAGS_REG))]
11010   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11011   "@
11012    sar{l}\t{%2, %0|%0, %2}
11013    sar{l}\t{%b2, %0|%0, %b2}"
11014   [(set_attr "type" "ishift")
11015    (set_attr "mode" "SI")])
11017 (define_insn "*ashrsi3_1_zext"
11018   [(set (match_operand:DI 0 "register_operand" "=r,r")
11019         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11020                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11021    (clobber (reg:CC FLAGS_REG))]
11022   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11023   "@
11024    sar{l}\t{%2, %k0|%k0, %2}
11025    sar{l}\t{%b2, %k0|%k0, %b2}"
11026   [(set_attr "type" "ishift")
11027    (set_attr "mode" "SI")])
11029 ;; This pattern can't accept a variable shift count, since shifts by
11030 ;; zero don't affect the flags.  We assume that shifts by constant
11031 ;; zero are optimized away.
11032 (define_insn "*ashrsi3_one_bit_cmp"
11033   [(set (reg FLAGS_REG)
11034         (compare
11035           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11036                        (match_operand:QI 2 "const1_operand" ""))
11037           (const_int 0)))
11038    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11039         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11040   "ix86_match_ccmode (insn, CCGOCmode)
11041    && (TARGET_SHIFT1 || optimize_size)
11042    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11043   "sar{l}\t%0"
11044   [(set_attr "type" "ishift")
11045    (set (attr "length") 
11046      (if_then_else (match_operand:SI 0 "register_operand" "") 
11047         (const_string "2")
11048         (const_string "*")))])
11050 (define_insn "*ashrsi3_one_bit_cmp_zext"
11051   [(set (reg FLAGS_REG)
11052         (compare
11053           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11054                        (match_operand:QI 2 "const1_operand" ""))
11055           (const_int 0)))
11056    (set (match_operand:DI 0 "register_operand" "=r")
11057         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11058   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11059    && (TARGET_SHIFT1 || optimize_size)
11060    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11061   "sar{l}\t%k0"
11062   [(set_attr "type" "ishift")
11063    (set_attr "length" "2")])
11065 ;; This pattern can't accept a variable shift count, since shifts by
11066 ;; zero don't affect the flags.  We assume that shifts by constant
11067 ;; zero are optimized away.
11068 (define_insn "*ashrsi3_cmp"
11069   [(set (reg FLAGS_REG)
11070         (compare
11071           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11072                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11073           (const_int 0)))
11074    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11075         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11076   "ix86_match_ccmode (insn, CCGOCmode)
11077    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11078   "sar{l}\t{%2, %0|%0, %2}"
11079   [(set_attr "type" "ishift")
11080    (set_attr "mode" "SI")])
11082 (define_insn "*ashrsi3_cmp_zext"
11083   [(set (reg FLAGS_REG)
11084         (compare
11085           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11086                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11087           (const_int 0)))
11088    (set (match_operand:DI 0 "register_operand" "=r")
11089         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11090   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11091    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11092   "sar{l}\t{%2, %k0|%k0, %2}"
11093   [(set_attr "type" "ishift")
11094    (set_attr "mode" "SI")])
11096 (define_expand "ashrhi3"
11097   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11098         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11099                      (match_operand:QI 2 "nonmemory_operand" "")))
11100    (clobber (reg:CC FLAGS_REG))]
11101   "TARGET_HIMODE_MATH"
11102   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11104 (define_insn "*ashrhi3_1_one_bit"
11105   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11106         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11107                      (match_operand:QI 2 "const1_operand" "")))
11108    (clobber (reg:CC FLAGS_REG))]
11109   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11110    && (TARGET_SHIFT1 || optimize_size)"
11111   "sar{w}\t%0"
11112   [(set_attr "type" "ishift")
11113    (set (attr "length") 
11114      (if_then_else (match_operand 0 "register_operand" "") 
11115         (const_string "2")
11116         (const_string "*")))])
11118 (define_insn "*ashrhi3_1"
11119   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11120         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11121                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11122    (clobber (reg:CC FLAGS_REG))]
11123   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11124   "@
11125    sar{w}\t{%2, %0|%0, %2}
11126    sar{w}\t{%b2, %0|%0, %b2}"
11127   [(set_attr "type" "ishift")
11128    (set_attr "mode" "HI")])
11130 ;; This pattern can't accept a variable shift count, since shifts by
11131 ;; zero don't affect the flags.  We assume that shifts by constant
11132 ;; zero are optimized away.
11133 (define_insn "*ashrhi3_one_bit_cmp"
11134   [(set (reg FLAGS_REG)
11135         (compare
11136           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11137                        (match_operand:QI 2 "const1_operand" ""))
11138           (const_int 0)))
11139    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11140         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11141   "ix86_match_ccmode (insn, CCGOCmode)
11142    && (TARGET_SHIFT1 || optimize_size)
11143    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11144   "sar{w}\t%0"
11145   [(set_attr "type" "ishift")
11146    (set (attr "length") 
11147      (if_then_else (match_operand 0 "register_operand" "") 
11148         (const_string "2")
11149         (const_string "*")))])
11151 ;; This pattern can't accept a variable shift count, since shifts by
11152 ;; zero don't affect the flags.  We assume that shifts by constant
11153 ;; zero are optimized away.
11154 (define_insn "*ashrhi3_cmp"
11155   [(set (reg FLAGS_REG)
11156         (compare
11157           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11158                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11159           (const_int 0)))
11160    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11161         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11162   "ix86_match_ccmode (insn, CCGOCmode)
11163    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11164   "sar{w}\t{%2, %0|%0, %2}"
11165   [(set_attr "type" "ishift")
11166    (set_attr "mode" "HI")])
11168 (define_expand "ashrqi3"
11169   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11170         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11171                      (match_operand:QI 2 "nonmemory_operand" "")))
11172    (clobber (reg:CC FLAGS_REG))]
11173   "TARGET_QIMODE_MATH"
11174   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11176 (define_insn "*ashrqi3_1_one_bit"
11177   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11178         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11179                      (match_operand:QI 2 "const1_operand" "")))
11180    (clobber (reg:CC FLAGS_REG))]
11181   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11182    && (TARGET_SHIFT1 || optimize_size)"
11183   "sar{b}\t%0"
11184   [(set_attr "type" "ishift")
11185    (set (attr "length") 
11186      (if_then_else (match_operand 0 "register_operand" "") 
11187         (const_string "2")
11188         (const_string "*")))])
11190 (define_insn "*ashrqi3_1_one_bit_slp"
11191   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11192         (ashiftrt:QI (match_dup 0)
11193                      (match_operand:QI 1 "const1_operand" "")))
11194    (clobber (reg:CC FLAGS_REG))]
11195   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11196    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11197    && (TARGET_SHIFT1 || optimize_size)"
11198   "sar{b}\t%0"
11199   [(set_attr "type" "ishift1")
11200    (set (attr "length") 
11201      (if_then_else (match_operand 0 "register_operand" "") 
11202         (const_string "2")
11203         (const_string "*")))])
11205 (define_insn "*ashrqi3_1"
11206   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11207         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11208                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11209    (clobber (reg:CC FLAGS_REG))]
11210   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11211   "@
11212    sar{b}\t{%2, %0|%0, %2}
11213    sar{b}\t{%b2, %0|%0, %b2}"
11214   [(set_attr "type" "ishift")
11215    (set_attr "mode" "QI")])
11217 (define_insn "*ashrqi3_1_slp"
11218   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11219         (ashiftrt:QI (match_dup 0)
11220                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11221    (clobber (reg:CC FLAGS_REG))]
11222   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11223    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11224   "@
11225    sar{b}\t{%1, %0|%0, %1}
11226    sar{b}\t{%b1, %0|%0, %b1}"
11227   [(set_attr "type" "ishift1")
11228    (set_attr "mode" "QI")])
11230 ;; This pattern can't accept a variable shift count, since shifts by
11231 ;; zero don't affect the flags.  We assume that shifts by constant
11232 ;; zero are optimized away.
11233 (define_insn "*ashrqi3_one_bit_cmp"
11234   [(set (reg FLAGS_REG)
11235         (compare
11236           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11237                        (match_operand:QI 2 "const1_operand" "I"))
11238           (const_int 0)))
11239    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11240         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11241   "ix86_match_ccmode (insn, CCGOCmode)
11242    && (TARGET_SHIFT1 || optimize_size)
11243    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11244   "sar{b}\t%0"
11245   [(set_attr "type" "ishift")
11246    (set (attr "length") 
11247      (if_then_else (match_operand 0 "register_operand" "") 
11248         (const_string "2")
11249         (const_string "*")))])
11251 ;; This pattern can't accept a variable shift count, since shifts by
11252 ;; zero don't affect the flags.  We assume that shifts by constant
11253 ;; zero are optimized away.
11254 (define_insn "*ashrqi3_cmp"
11255   [(set (reg FLAGS_REG)
11256         (compare
11257           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11258                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11259           (const_int 0)))
11260    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11261         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11262   "ix86_match_ccmode (insn, CCGOCmode)
11263    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11264   "sar{b}\t{%2, %0|%0, %2}"
11265   [(set_attr "type" "ishift")
11266    (set_attr "mode" "QI")])
11268 ;; Logical shift instructions
11270 ;; See comment above `ashldi3' about how this works.
11272 (define_expand "lshrdi3"
11273   [(set (match_operand:DI 0 "shiftdi_operand" "")
11274         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11275                      (match_operand:QI 2 "nonmemory_operand" "")))]
11276   ""
11277   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11279 (define_insn "*lshrdi3_1_one_bit_rex64"
11280   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11281         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11282                      (match_operand:QI 2 "const1_operand" "")))
11283    (clobber (reg:CC FLAGS_REG))]
11284   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11285    && (TARGET_SHIFT1 || optimize_size)"
11286   "shr{q}\t%0"
11287   [(set_attr "type" "ishift")
11288    (set (attr "length") 
11289      (if_then_else (match_operand:DI 0 "register_operand" "") 
11290         (const_string "2")
11291         (const_string "*")))])
11293 (define_insn "*lshrdi3_1_rex64"
11294   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11295         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11296                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11297    (clobber (reg:CC FLAGS_REG))]
11298   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11299   "@
11300    shr{q}\t{%2, %0|%0, %2}
11301    shr{q}\t{%b2, %0|%0, %b2}"
11302   [(set_attr "type" "ishift")
11303    (set_attr "mode" "DI")])
11305 ;; This pattern can't accept a variable shift count, since shifts by
11306 ;; zero don't affect the flags.  We assume that shifts by constant
11307 ;; zero are optimized away.
11308 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11309   [(set (reg FLAGS_REG)
11310         (compare
11311           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11312                        (match_operand:QI 2 "const1_operand" ""))
11313           (const_int 0)))
11314    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11315         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11316   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11317    && (TARGET_SHIFT1 || optimize_size)
11318    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11319   "shr{q}\t%0"
11320   [(set_attr "type" "ishift")
11321    (set (attr "length") 
11322      (if_then_else (match_operand:DI 0 "register_operand" "") 
11323         (const_string "2")
11324         (const_string "*")))])
11326 ;; This pattern can't accept a variable shift count, since shifts by
11327 ;; zero don't affect the flags.  We assume that shifts by constant
11328 ;; zero are optimized away.
11329 (define_insn "*lshrdi3_cmp_rex64"
11330   [(set (reg FLAGS_REG)
11331         (compare
11332           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11333                        (match_operand:QI 2 "const_int_operand" "e"))
11334           (const_int 0)))
11335    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11336         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11337   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11338    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11339   "shr{q}\t{%2, %0|%0, %2}"
11340   [(set_attr "type" "ishift")
11341    (set_attr "mode" "DI")])
11343 (define_insn "*lshrdi3_1"
11344   [(set (match_operand:DI 0 "register_operand" "=r")
11345         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11346                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11347    (clobber (reg:CC FLAGS_REG))]
11348   "!TARGET_64BIT"
11349   "#"
11350   [(set_attr "type" "multi")])
11352 ;; By default we don't ask for a scratch register, because when DImode
11353 ;; values are manipulated, registers are already at a premium.  But if
11354 ;; we have one handy, we won't turn it away.
11355 (define_peephole2
11356   [(match_scratch:SI 3 "r")
11357    (parallel [(set (match_operand:DI 0 "register_operand" "")
11358                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11359                                 (match_operand:QI 2 "nonmemory_operand" "")))
11360               (clobber (reg:CC FLAGS_REG))])
11361    (match_dup 3)]
11362   "!TARGET_64BIT && TARGET_CMOVE"
11363   [(const_int 0)]
11364   "ix86_split_lshrdi (operands, operands[3]); DONE;")
11366 (define_split 
11367   [(set (match_operand:DI 0 "register_operand" "")
11368         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11369                      (match_operand:QI 2 "nonmemory_operand" "")))
11370    (clobber (reg:CC FLAGS_REG))]
11371   "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11372   [(const_int 0)]
11373   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11375 (define_expand "lshrsi3"
11376   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11377         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11378                      (match_operand:QI 2 "nonmemory_operand" "")))
11379    (clobber (reg:CC FLAGS_REG))]
11380   ""
11381   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11383 (define_insn "*lshrsi3_1_one_bit"
11384   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11385         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11386                      (match_operand:QI 2 "const1_operand" "")))
11387    (clobber (reg:CC FLAGS_REG))]
11388   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11389    && (TARGET_SHIFT1 || optimize_size)"
11390   "shr{l}\t%0"
11391   [(set_attr "type" "ishift")
11392    (set (attr "length") 
11393      (if_then_else (match_operand:SI 0 "register_operand" "") 
11394         (const_string "2")
11395         (const_string "*")))])
11397 (define_insn "*lshrsi3_1_one_bit_zext"
11398   [(set (match_operand:DI 0 "register_operand" "=r")
11399         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11400                      (match_operand:QI 2 "const1_operand" "")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11403    && (TARGET_SHIFT1 || optimize_size)"
11404   "shr{l}\t%k0"
11405   [(set_attr "type" "ishift")
11406    (set_attr "length" "2")])
11408 (define_insn "*lshrsi3_1"
11409   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11410         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11411                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11412    (clobber (reg:CC FLAGS_REG))]
11413   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11414   "@
11415    shr{l}\t{%2, %0|%0, %2}
11416    shr{l}\t{%b2, %0|%0, %b2}"
11417   [(set_attr "type" "ishift")
11418    (set_attr "mode" "SI")])
11420 (define_insn "*lshrsi3_1_zext"
11421   [(set (match_operand:DI 0 "register_operand" "=r,r")
11422         (zero_extend:DI
11423           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11424                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11425    (clobber (reg:CC FLAGS_REG))]
11426   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11427   "@
11428    shr{l}\t{%2, %k0|%k0, %2}
11429    shr{l}\t{%b2, %k0|%k0, %b2}"
11430   [(set_attr "type" "ishift")
11431    (set_attr "mode" "SI")])
11433 ;; This pattern can't accept a variable shift count, since shifts by
11434 ;; zero don't affect the flags.  We assume that shifts by constant
11435 ;; zero are optimized away.
11436 (define_insn "*lshrsi3_one_bit_cmp"
11437   [(set (reg FLAGS_REG)
11438         (compare
11439           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11440                        (match_operand:QI 2 "const1_operand" ""))
11441           (const_int 0)))
11442    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11443         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11444   "ix86_match_ccmode (insn, CCGOCmode)
11445    && (TARGET_SHIFT1 || optimize_size)
11446    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11447   "shr{l}\t%0"
11448   [(set_attr "type" "ishift")
11449    (set (attr "length") 
11450      (if_then_else (match_operand:SI 0 "register_operand" "") 
11451         (const_string "2")
11452         (const_string "*")))])
11454 (define_insn "*lshrsi3_cmp_one_bit_zext"
11455   [(set (reg FLAGS_REG)
11456         (compare
11457           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11458                        (match_operand:QI 2 "const1_operand" ""))
11459           (const_int 0)))
11460    (set (match_operand:DI 0 "register_operand" "=r")
11461         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11462   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11463    && (TARGET_SHIFT1 || optimize_size)
11464    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11465   "shr{l}\t%k0"
11466   [(set_attr "type" "ishift")
11467    (set_attr "length" "2")])
11469 ;; This pattern can't accept a variable shift count, since shifts by
11470 ;; zero don't affect the flags.  We assume that shifts by constant
11471 ;; zero are optimized away.
11472 (define_insn "*lshrsi3_cmp"
11473   [(set (reg FLAGS_REG)
11474         (compare
11475           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11476                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11477           (const_int 0)))
11478    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11479         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11480   "ix86_match_ccmode (insn, CCGOCmode)
11481    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11482   "shr{l}\t{%2, %0|%0, %2}"
11483   [(set_attr "type" "ishift")
11484    (set_attr "mode" "SI")])
11486 (define_insn "*lshrsi3_cmp_zext"
11487   [(set (reg FLAGS_REG)
11488         (compare
11489           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11490                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11491           (const_int 0)))
11492    (set (match_operand:DI 0 "register_operand" "=r")
11493         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11494   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11495    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11496   "shr{l}\t{%2, %k0|%k0, %2}"
11497   [(set_attr "type" "ishift")
11498    (set_attr "mode" "SI")])
11500 (define_expand "lshrhi3"
11501   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11502         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11503                      (match_operand:QI 2 "nonmemory_operand" "")))
11504    (clobber (reg:CC FLAGS_REG))]
11505   "TARGET_HIMODE_MATH"
11506   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11508 (define_insn "*lshrhi3_1_one_bit"
11509   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11510         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11511                      (match_operand:QI 2 "const1_operand" "")))
11512    (clobber (reg:CC FLAGS_REG))]
11513   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11514    && (TARGET_SHIFT1 || optimize_size)"
11515   "shr{w}\t%0"
11516   [(set_attr "type" "ishift")
11517    (set (attr "length") 
11518      (if_then_else (match_operand 0 "register_operand" "") 
11519         (const_string "2")
11520         (const_string "*")))])
11522 (define_insn "*lshrhi3_1"
11523   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11524         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11525                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11526    (clobber (reg:CC FLAGS_REG))]
11527   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11528   "@
11529    shr{w}\t{%2, %0|%0, %2}
11530    shr{w}\t{%b2, %0|%0, %b2}"
11531   [(set_attr "type" "ishift")
11532    (set_attr "mode" "HI")])
11534 ;; This pattern can't accept a variable shift count, since shifts by
11535 ;; zero don't affect the flags.  We assume that shifts by constant
11536 ;; zero are optimized away.
11537 (define_insn "*lshrhi3_one_bit_cmp"
11538   [(set (reg FLAGS_REG)
11539         (compare
11540           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11541                        (match_operand:QI 2 "const1_operand" ""))
11542           (const_int 0)))
11543    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11544         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11545   "ix86_match_ccmode (insn, CCGOCmode)
11546    && (TARGET_SHIFT1 || optimize_size)
11547    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11548   "shr{w}\t%0"
11549   [(set_attr "type" "ishift")
11550    (set (attr "length") 
11551      (if_then_else (match_operand:SI 0 "register_operand" "") 
11552         (const_string "2")
11553         (const_string "*")))])
11555 ;; This pattern can't accept a variable shift count, since shifts by
11556 ;; zero don't affect the flags.  We assume that shifts by constant
11557 ;; zero are optimized away.
11558 (define_insn "*lshrhi3_cmp"
11559   [(set (reg FLAGS_REG)
11560         (compare
11561           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11562                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11563           (const_int 0)))
11564    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11565         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11566   "ix86_match_ccmode (insn, CCGOCmode)
11567    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11568   "shr{w}\t{%2, %0|%0, %2}"
11569   [(set_attr "type" "ishift")
11570    (set_attr "mode" "HI")])
11572 (define_expand "lshrqi3"
11573   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11574         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11575                      (match_operand:QI 2 "nonmemory_operand" "")))
11576    (clobber (reg:CC FLAGS_REG))]
11577   "TARGET_QIMODE_MATH"
11578   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11580 (define_insn "*lshrqi3_1_one_bit"
11581   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11582         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11583                      (match_operand:QI 2 "const1_operand" "")))
11584    (clobber (reg:CC FLAGS_REG))]
11585   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11586    && (TARGET_SHIFT1 || optimize_size)"
11587   "shr{b}\t%0"
11588   [(set_attr "type" "ishift")
11589    (set (attr "length") 
11590      (if_then_else (match_operand 0 "register_operand" "") 
11591         (const_string "2")
11592         (const_string "*")))])
11594 (define_insn "*lshrqi3_1_one_bit_slp"
11595   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11596         (lshiftrt:QI (match_dup 0)
11597                      (match_operand:QI 1 "const1_operand" "")))
11598    (clobber (reg:CC FLAGS_REG))]
11599   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11600    && (TARGET_SHIFT1 || optimize_size)"
11601   "shr{b}\t%0"
11602   [(set_attr "type" "ishift1")
11603    (set (attr "length") 
11604      (if_then_else (match_operand 0 "register_operand" "") 
11605         (const_string "2")
11606         (const_string "*")))])
11608 (define_insn "*lshrqi3_1"
11609   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11610         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11611                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11612    (clobber (reg:CC FLAGS_REG))]
11613   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11614   "@
11615    shr{b}\t{%2, %0|%0, %2}
11616    shr{b}\t{%b2, %0|%0, %b2}"
11617   [(set_attr "type" "ishift")
11618    (set_attr "mode" "QI")])
11620 (define_insn "*lshrqi3_1_slp"
11621   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11622         (lshiftrt:QI (match_dup 0)
11623                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11624    (clobber (reg:CC FLAGS_REG))]
11625   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11626    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11627   "@
11628    shr{b}\t{%1, %0|%0, %1}
11629    shr{b}\t{%b1, %0|%0, %b1}"
11630   [(set_attr "type" "ishift1")
11631    (set_attr "mode" "QI")])
11633 ;; This pattern can't accept a variable shift count, since shifts by
11634 ;; zero don't affect the flags.  We assume that shifts by constant
11635 ;; zero are optimized away.
11636 (define_insn "*lshrqi2_one_bit_cmp"
11637   [(set (reg FLAGS_REG)
11638         (compare
11639           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11640                        (match_operand:QI 2 "const1_operand" ""))
11641           (const_int 0)))
11642    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11643         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11644   "ix86_match_ccmode (insn, CCGOCmode)
11645    && (TARGET_SHIFT1 || optimize_size)
11646    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11647   "shr{b}\t%0"
11648   [(set_attr "type" "ishift")
11649    (set (attr "length") 
11650      (if_then_else (match_operand:SI 0 "register_operand" "") 
11651         (const_string "2")
11652         (const_string "*")))])
11654 ;; This pattern can't accept a variable shift count, since shifts by
11655 ;; zero don't affect the flags.  We assume that shifts by constant
11656 ;; zero are optimized away.
11657 (define_insn "*lshrqi2_cmp"
11658   [(set (reg FLAGS_REG)
11659         (compare
11660           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11661                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11662           (const_int 0)))
11663    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11664         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11665   "ix86_match_ccmode (insn, CCGOCmode)
11666    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11667   "shr{b}\t{%2, %0|%0, %2}"
11668   [(set_attr "type" "ishift")
11669    (set_attr "mode" "QI")])
11671 ;; Rotate instructions
11673 (define_expand "rotldi3"
11674   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11675         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11676                    (match_operand:QI 2 "nonmemory_operand" "")))
11677    (clobber (reg:CC FLAGS_REG))]
11678   "TARGET_64BIT"
11679   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11681 (define_insn "*rotlsi3_1_one_bit_rex64"
11682   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11683         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11684                    (match_operand:QI 2 "const1_operand" "")))
11685    (clobber (reg:CC FLAGS_REG))]
11686   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11687    && (TARGET_SHIFT1 || optimize_size)"
11688   "rol{q}\t%0"
11689   [(set_attr "type" "rotate")
11690    (set (attr "length") 
11691      (if_then_else (match_operand:DI 0 "register_operand" "") 
11692         (const_string "2")
11693         (const_string "*")))])
11695 (define_insn "*rotldi3_1_rex64"
11696   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11697         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11698                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
11699    (clobber (reg:CC FLAGS_REG))]
11700   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11701   "@
11702    rol{q}\t{%2, %0|%0, %2}
11703    rol{q}\t{%b2, %0|%0, %b2}"
11704   [(set_attr "type" "rotate")
11705    (set_attr "mode" "DI")])
11707 (define_expand "rotlsi3"
11708   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11709         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11710                    (match_operand:QI 2 "nonmemory_operand" "")))
11711    (clobber (reg:CC FLAGS_REG))]
11712   ""
11713   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11715 (define_insn "*rotlsi3_1_one_bit"
11716   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11717         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11718                    (match_operand:QI 2 "const1_operand" "")))
11719    (clobber (reg:CC FLAGS_REG))]
11720   "ix86_binary_operator_ok (ROTATE, SImode, operands)
11721    && (TARGET_SHIFT1 || optimize_size)"
11722   "rol{l}\t%0"
11723   [(set_attr "type" "rotate")
11724    (set (attr "length") 
11725      (if_then_else (match_operand:SI 0 "register_operand" "") 
11726         (const_string "2")
11727         (const_string "*")))])
11729 (define_insn "*rotlsi3_1_one_bit_zext"
11730   [(set (match_operand:DI 0 "register_operand" "=r")
11731         (zero_extend:DI
11732           (rotate:SI (match_operand:SI 1 "register_operand" "0")
11733                      (match_operand:QI 2 "const1_operand" ""))))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11736    && (TARGET_SHIFT1 || optimize_size)"
11737   "rol{l}\t%k0"
11738   [(set_attr "type" "rotate")
11739    (set_attr "length" "2")])
11741 (define_insn "*rotlsi3_1"
11742   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11743         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11744                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11745    (clobber (reg:CC FLAGS_REG))]
11746   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11747   "@
11748    rol{l}\t{%2, %0|%0, %2}
11749    rol{l}\t{%b2, %0|%0, %b2}"
11750   [(set_attr "type" "rotate")
11751    (set_attr "mode" "SI")])
11753 (define_insn "*rotlsi3_1_zext"
11754   [(set (match_operand:DI 0 "register_operand" "=r,r")
11755         (zero_extend:DI
11756           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11757                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11758    (clobber (reg:CC FLAGS_REG))]
11759   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11760   "@
11761    rol{l}\t{%2, %k0|%k0, %2}
11762    rol{l}\t{%b2, %k0|%k0, %b2}"
11763   [(set_attr "type" "rotate")
11764    (set_attr "mode" "SI")])
11766 (define_expand "rotlhi3"
11767   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11768         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11769                    (match_operand:QI 2 "nonmemory_operand" "")))
11770    (clobber (reg:CC FLAGS_REG))]
11771   "TARGET_HIMODE_MATH"
11772   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11774 (define_insn "*rotlhi3_1_one_bit"
11775   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11776         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11777                    (match_operand:QI 2 "const1_operand" "")))
11778    (clobber (reg:CC FLAGS_REG))]
11779   "ix86_binary_operator_ok (ROTATE, HImode, operands)
11780    && (TARGET_SHIFT1 || optimize_size)"
11781   "rol{w}\t%0"
11782   [(set_attr "type" "rotate")
11783    (set (attr "length") 
11784      (if_then_else (match_operand 0 "register_operand" "") 
11785         (const_string "2")
11786         (const_string "*")))])
11788 (define_insn "*rotlhi3_1"
11789   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11790         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11791                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11792    (clobber (reg:CC FLAGS_REG))]
11793   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11794   "@
11795    rol{w}\t{%2, %0|%0, %2}
11796    rol{w}\t{%b2, %0|%0, %b2}"
11797   [(set_attr "type" "rotate")
11798    (set_attr "mode" "HI")])
11800 (define_expand "rotlqi3"
11801   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11802         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11803                    (match_operand:QI 2 "nonmemory_operand" "")))
11804    (clobber (reg:CC FLAGS_REG))]
11805   "TARGET_QIMODE_MATH"
11806   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11808 (define_insn "*rotlqi3_1_one_bit_slp"
11809   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11810         (rotate:QI (match_dup 0)
11811                    (match_operand:QI 1 "const1_operand" "")))
11812    (clobber (reg:CC FLAGS_REG))]
11813   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11814    && (TARGET_SHIFT1 || optimize_size)"
11815   "rol{b}\t%0"
11816   [(set_attr "type" "rotate1")
11817    (set (attr "length") 
11818      (if_then_else (match_operand 0 "register_operand" "") 
11819         (const_string "2")
11820         (const_string "*")))])
11822 (define_insn "*rotlqi3_1_one_bit"
11823   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11824         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11825                    (match_operand:QI 2 "const1_operand" "")))
11826    (clobber (reg:CC FLAGS_REG))]
11827   "ix86_binary_operator_ok (ROTATE, QImode, operands)
11828    && (TARGET_SHIFT1 || optimize_size)"
11829   "rol{b}\t%0"
11830   [(set_attr "type" "rotate")
11831    (set (attr "length") 
11832      (if_then_else (match_operand 0 "register_operand" "") 
11833         (const_string "2")
11834         (const_string "*")))])
11836 (define_insn "*rotlqi3_1_slp"
11837   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11838         (rotate:QI (match_dup 0)
11839                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
11840    (clobber (reg:CC FLAGS_REG))]
11841   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11842    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11843   "@
11844    rol{b}\t{%1, %0|%0, %1}
11845    rol{b}\t{%b1, %0|%0, %b1}"
11846   [(set_attr "type" "rotate1")
11847    (set_attr "mode" "QI")])
11849 (define_insn "*rotlqi3_1"
11850   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11851         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11852                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11855   "@
11856    rol{b}\t{%2, %0|%0, %2}
11857    rol{b}\t{%b2, %0|%0, %b2}"
11858   [(set_attr "type" "rotate")
11859    (set_attr "mode" "QI")])
11861 (define_expand "rotrdi3"
11862   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11863         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11864                      (match_operand:QI 2 "nonmemory_operand" "")))
11865    (clobber (reg:CC FLAGS_REG))]
11866   "TARGET_64BIT"
11867   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11869 (define_insn "*rotrdi3_1_one_bit_rex64"
11870   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11871         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11872                      (match_operand:QI 2 "const1_operand" "")))
11873    (clobber (reg:CC FLAGS_REG))]
11874   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11875    && (TARGET_SHIFT1 || optimize_size)"
11876   "ror{q}\t%0"
11877   [(set_attr "type" "rotate")
11878    (set (attr "length") 
11879      (if_then_else (match_operand:DI 0 "register_operand" "") 
11880         (const_string "2")
11881         (const_string "*")))])
11883 (define_insn "*rotrdi3_1_rex64"
11884   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11885         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11886                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11887    (clobber (reg:CC FLAGS_REG))]
11888   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11889   "@
11890    ror{q}\t{%2, %0|%0, %2}
11891    ror{q}\t{%b2, %0|%0, %b2}"
11892   [(set_attr "type" "rotate")
11893    (set_attr "mode" "DI")])
11895 (define_expand "rotrsi3"
11896   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11897         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11898                      (match_operand:QI 2 "nonmemory_operand" "")))
11899    (clobber (reg:CC FLAGS_REG))]
11900   ""
11901   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11903 (define_insn "*rotrsi3_1_one_bit"
11904   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11905         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11906                      (match_operand:QI 2 "const1_operand" "")))
11907    (clobber (reg:CC FLAGS_REG))]
11908   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11909    && (TARGET_SHIFT1 || optimize_size)"
11910   "ror{l}\t%0"
11911   [(set_attr "type" "rotate")
11912    (set (attr "length") 
11913      (if_then_else (match_operand:SI 0 "register_operand" "") 
11914         (const_string "2")
11915         (const_string "*")))])
11917 (define_insn "*rotrsi3_1_one_bit_zext"
11918   [(set (match_operand:DI 0 "register_operand" "=r")
11919         (zero_extend:DI
11920           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11921                        (match_operand:QI 2 "const1_operand" ""))))
11922    (clobber (reg:CC FLAGS_REG))]
11923   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11924    && (TARGET_SHIFT1 || optimize_size)"
11925   "ror{l}\t%k0"
11926   [(set_attr "type" "rotate")
11927    (set (attr "length") 
11928      (if_then_else (match_operand:SI 0 "register_operand" "") 
11929         (const_string "2")
11930         (const_string "*")))])
11932 (define_insn "*rotrsi3_1"
11933   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11934         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11935                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11936    (clobber (reg:CC FLAGS_REG))]
11937   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11938   "@
11939    ror{l}\t{%2, %0|%0, %2}
11940    ror{l}\t{%b2, %0|%0, %b2}"
11941   [(set_attr "type" "rotate")
11942    (set_attr "mode" "SI")])
11944 (define_insn "*rotrsi3_1_zext"
11945   [(set (match_operand:DI 0 "register_operand" "=r,r")
11946         (zero_extend:DI
11947           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11948                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11949    (clobber (reg:CC FLAGS_REG))]
11950   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11951   "@
11952    ror{l}\t{%2, %k0|%k0, %2}
11953    ror{l}\t{%b2, %k0|%k0, %b2}"
11954   [(set_attr "type" "rotate")
11955    (set_attr "mode" "SI")])
11957 (define_expand "rotrhi3"
11958   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11959         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11960                      (match_operand:QI 2 "nonmemory_operand" "")))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "TARGET_HIMODE_MATH"
11963   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11965 (define_insn "*rotrhi3_one_bit"
11966   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11967         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11968                      (match_operand:QI 2 "const1_operand" "")))
11969    (clobber (reg:CC FLAGS_REG))]
11970   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11971    && (TARGET_SHIFT1 || optimize_size)"
11972   "ror{w}\t%0"
11973   [(set_attr "type" "rotate")
11974    (set (attr "length") 
11975      (if_then_else (match_operand 0 "register_operand" "") 
11976         (const_string "2")
11977         (const_string "*")))])
11979 (define_insn "*rotrhi3"
11980   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11981         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11982                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11983    (clobber (reg:CC FLAGS_REG))]
11984   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11985   "@
11986    ror{w}\t{%2, %0|%0, %2}
11987    ror{w}\t{%b2, %0|%0, %b2}"
11988   [(set_attr "type" "rotate")
11989    (set_attr "mode" "HI")])
11991 (define_expand "rotrqi3"
11992   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11993         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
11994                      (match_operand:QI 2 "nonmemory_operand" "")))
11995    (clobber (reg:CC FLAGS_REG))]
11996   "TARGET_QIMODE_MATH"
11997   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
11999 (define_insn "*rotrqi3_1_one_bit"
12000   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12001         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12002                      (match_operand:QI 2 "const1_operand" "")))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12005    && (TARGET_SHIFT1 || optimize_size)"
12006   "ror{b}\t%0"
12007   [(set_attr "type" "rotate")
12008    (set (attr "length") 
12009      (if_then_else (match_operand 0 "register_operand" "") 
12010         (const_string "2")
12011         (const_string "*")))])
12013 (define_insn "*rotrqi3_1_one_bit_slp"
12014   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12015         (rotatert:QI (match_dup 0)
12016                      (match_operand:QI 1 "const1_operand" "")))
12017    (clobber (reg:CC FLAGS_REG))]
12018   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12019    && (TARGET_SHIFT1 || optimize_size)"
12020   "ror{b}\t%0"
12021   [(set_attr "type" "rotate1")
12022    (set (attr "length") 
12023      (if_then_else (match_operand 0 "register_operand" "") 
12024         (const_string "2")
12025         (const_string "*")))])
12027 (define_insn "*rotrqi3_1"
12028   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12029         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12030                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12031    (clobber (reg:CC FLAGS_REG))]
12032   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12033   "@
12034    ror{b}\t{%2, %0|%0, %2}
12035    ror{b}\t{%b2, %0|%0, %b2}"
12036   [(set_attr "type" "rotate")
12037    (set_attr "mode" "QI")])
12039 (define_insn "*rotrqi3_1_slp"
12040   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12041         (rotatert:QI (match_dup 0)
12042                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12043    (clobber (reg:CC FLAGS_REG))]
12044   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12045    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12046   "@
12047    ror{b}\t{%1, %0|%0, %1}
12048    ror{b}\t{%b1, %0|%0, %b1}"
12049   [(set_attr "type" "rotate1")
12050    (set_attr "mode" "QI")])
12052 ;; Bit set / bit test instructions
12054 (define_expand "extv"
12055   [(set (match_operand:SI 0 "register_operand" "")
12056         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12057                          (match_operand:SI 2 "immediate_operand" "")
12058                          (match_operand:SI 3 "immediate_operand" "")))]
12059   ""
12061   /* Handle extractions from %ah et al.  */
12062   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12063     FAIL;
12065   /* From mips.md: extract_bit_field doesn't verify that our source
12066      matches the predicate, so check it again here.  */
12067   if (! ext_register_operand (operands[1], VOIDmode))
12068     FAIL;
12071 (define_expand "extzv"
12072   [(set (match_operand:SI 0 "register_operand" "")
12073         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12074                          (match_operand:SI 2 "immediate_operand" "")
12075                          (match_operand:SI 3 "immediate_operand" "")))]
12076   ""
12078   /* Handle extractions from %ah et al.  */
12079   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12080     FAIL;
12082   /* From mips.md: extract_bit_field doesn't verify that our source
12083      matches the predicate, so check it again here.  */
12084   if (! ext_register_operand (operands[1], VOIDmode))
12085     FAIL;
12088 (define_expand "insv"
12089   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12090                       (match_operand 1 "immediate_operand" "")
12091                       (match_operand 2 "immediate_operand" ""))
12092         (match_operand 3 "register_operand" ""))]
12093   ""
12095   /* Handle extractions from %ah et al.  */
12096   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12097     FAIL;
12099   /* From mips.md: insert_bit_field doesn't verify that our source
12100      matches the predicate, so check it again here.  */
12101   if (! ext_register_operand (operands[0], VOIDmode))
12102     FAIL;
12104   if (TARGET_64BIT)
12105     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12106   else
12107     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12109   DONE;
12112 ;; %%% bts, btr, btc, bt.
12113 ;; In general these instructions are *slow* when applied to memory,
12114 ;; since they enforce atomic operation.  When applied to registers,
12115 ;; it depends on the cpu implementation.  They're never faster than
12116 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12117 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12118 ;; within the instruction itself, so operating on bits in the high
12119 ;; 32-bits of a register becomes easier.
12121 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12122 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12123 ;; negdf respectively, so they can never be disabled entirely.
12125 (define_insn "*btsq"
12126   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12127                          (const_int 1)
12128                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12129         (const_int 1))
12130    (clobber (reg:CC FLAGS_REG))]
12131   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12132   "bts{q} %1,%0"
12133   [(set_attr "type" "alu1")])
12135 (define_insn "*btrq"
12136   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12137                          (const_int 1)
12138                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12139         (const_int 0))
12140    (clobber (reg:CC FLAGS_REG))]
12141   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12142   "btr{q} %1,%0"
12143   [(set_attr "type" "alu1")])
12145 (define_insn "*btcq"
12146   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12147                          (const_int 1)
12148                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12149         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12150    (clobber (reg:CC FLAGS_REG))]
12151   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12152   "btc{q} %1,%0"
12153   [(set_attr "type" "alu1")])
12155 ;; Allow Nocona to avoid these instructions if a register is available.
12157 (define_peephole2
12158   [(match_scratch:DI 2 "r")
12159    (parallel [(set (zero_extract:DI
12160                      (match_operand:DI 0 "register_operand" "")
12161                      (const_int 1)
12162                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12163                    (const_int 1))
12164               (clobber (reg:CC FLAGS_REG))])]
12165   "TARGET_64BIT && !TARGET_USE_BT"
12166   [(const_int 0)]
12168   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12169   rtx op1;
12171   if (HOST_BITS_PER_WIDE_INT >= 64)
12172     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12173   else if (i < HOST_BITS_PER_WIDE_INT)
12174     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12175   else
12176     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12178   op1 = immed_double_const (lo, hi, DImode);
12179   if (i >= 31)
12180     {
12181       emit_move_insn (operands[2], op1);
12182       op1 = operands[2];
12183     }
12185   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12186   DONE;
12189 (define_peephole2
12190   [(match_scratch:DI 2 "r")
12191    (parallel [(set (zero_extract:DI
12192                      (match_operand:DI 0 "register_operand" "")
12193                      (const_int 1)
12194                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12195                    (const_int 0))
12196               (clobber (reg:CC FLAGS_REG))])]
12197   "TARGET_64BIT && !TARGET_USE_BT"
12198   [(const_int 0)]
12200   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12201   rtx op1;
12203   if (HOST_BITS_PER_WIDE_INT >= 64)
12204     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12205   else if (i < HOST_BITS_PER_WIDE_INT)
12206     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12207   else
12208     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12210   op1 = immed_double_const (~lo, ~hi, DImode);
12211   if (i >= 32)
12212     {
12213       emit_move_insn (operands[2], op1);
12214       op1 = operands[2];
12215     }
12217   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12218   DONE;
12221 (define_peephole2
12222   [(match_scratch:DI 2 "r")
12223    (parallel [(set (zero_extract:DI
12224                      (match_operand:DI 0 "register_operand" "")
12225                      (const_int 1)
12226                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12227               (not:DI (zero_extract:DI
12228                         (match_dup 0) (const_int 1) (match_dup 1))))
12229               (clobber (reg:CC FLAGS_REG))])]
12230   "TARGET_64BIT && !TARGET_USE_BT"
12231   [(const_int 0)]
12233   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12234   rtx op1;
12236   if (HOST_BITS_PER_WIDE_INT >= 64)
12237     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12238   else if (i < HOST_BITS_PER_WIDE_INT)
12239     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12240   else
12241     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12243   op1 = immed_double_const (lo, hi, DImode);
12244   if (i >= 31)
12245     {
12246       emit_move_insn (operands[2], op1);
12247       op1 = operands[2];
12248     }
12250   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12251   DONE;
12254 ;; Store-flag instructions.
12256 ;; For all sCOND expanders, also expand the compare or test insn that
12257 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12259 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12260 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12261 ;; way, which can later delete the movzx if only QImode is needed.
12263 (define_expand "seq"
12264   [(set (match_operand:QI 0 "register_operand" "")
12265         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12266   ""
12267   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12269 (define_expand "sne"
12270   [(set (match_operand:QI 0 "register_operand" "")
12271         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12272   ""
12273   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12275 (define_expand "sgt"
12276   [(set (match_operand:QI 0 "register_operand" "")
12277         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12278   ""
12279   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12281 (define_expand "sgtu"
12282   [(set (match_operand:QI 0 "register_operand" "")
12283         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12284   ""
12285   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12287 (define_expand "slt"
12288   [(set (match_operand:QI 0 "register_operand" "")
12289         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12290   ""
12291   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12293 (define_expand "sltu"
12294   [(set (match_operand:QI 0 "register_operand" "")
12295         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12296   ""
12297   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12299 (define_expand "sge"
12300   [(set (match_operand:QI 0 "register_operand" "")
12301         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12302   ""
12303   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12305 (define_expand "sgeu"
12306   [(set (match_operand:QI 0 "register_operand" "")
12307         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12308   ""
12309   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12311 (define_expand "sle"
12312   [(set (match_operand:QI 0 "register_operand" "")
12313         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12314   ""
12315   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12317 (define_expand "sleu"
12318   [(set (match_operand:QI 0 "register_operand" "")
12319         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12320   ""
12321   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12323 (define_expand "sunordered"
12324   [(set (match_operand:QI 0 "register_operand" "")
12325         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12326   "TARGET_80387 || TARGET_SSE"
12327   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12329 (define_expand "sordered"
12330   [(set (match_operand:QI 0 "register_operand" "")
12331         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12332   "TARGET_80387"
12333   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12335 (define_expand "suneq"
12336   [(set (match_operand:QI 0 "register_operand" "")
12337         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12338   "TARGET_80387 || TARGET_SSE"
12339   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12341 (define_expand "sunge"
12342   [(set (match_operand:QI 0 "register_operand" "")
12343         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12344   "TARGET_80387 || TARGET_SSE"
12345   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12347 (define_expand "sungt"
12348   [(set (match_operand:QI 0 "register_operand" "")
12349         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12350   "TARGET_80387 || TARGET_SSE"
12351   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12353 (define_expand "sunle"
12354   [(set (match_operand:QI 0 "register_operand" "")
12355         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12356   "TARGET_80387 || TARGET_SSE"
12357   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12359 (define_expand "sunlt"
12360   [(set (match_operand:QI 0 "register_operand" "")
12361         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12362   "TARGET_80387 || TARGET_SSE"
12363   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12365 (define_expand "sltgt"
12366   [(set (match_operand:QI 0 "register_operand" "")
12367         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12368   "TARGET_80387 || TARGET_SSE"
12369   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12371 (define_insn "*setcc_1"
12372   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12373         (match_operator:QI 1 "ix86_comparison_operator"
12374           [(reg FLAGS_REG) (const_int 0)]))]
12375   ""
12376   "set%C1\t%0"
12377   [(set_attr "type" "setcc")
12378    (set_attr "mode" "QI")])
12380 (define_insn "*setcc_2"
12381   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12382         (match_operator:QI 1 "ix86_comparison_operator"
12383           [(reg FLAGS_REG) (const_int 0)]))]
12384   ""
12385   "set%C1\t%0"
12386   [(set_attr "type" "setcc")
12387    (set_attr "mode" "QI")])
12389 ;; In general it is not safe to assume too much about CCmode registers,
12390 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12391 ;; conditions this is safe on x86, so help combine not create
12393 ;;      seta    %al
12394 ;;      testb   %al, %al
12395 ;;      sete    %al
12397 (define_split 
12398   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12399         (ne:QI (match_operator 1 "ix86_comparison_operator"
12400                  [(reg FLAGS_REG) (const_int 0)])
12401             (const_int 0)))]
12402   ""
12403   [(set (match_dup 0) (match_dup 1))]
12405   PUT_MODE (operands[1], QImode);
12408 (define_split 
12409   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12410         (ne:QI (match_operator 1 "ix86_comparison_operator"
12411                  [(reg FLAGS_REG) (const_int 0)])
12412             (const_int 0)))]
12413   ""
12414   [(set (match_dup 0) (match_dup 1))]
12416   PUT_MODE (operands[1], QImode);
12419 (define_split 
12420   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12421         (eq:QI (match_operator 1 "ix86_comparison_operator"
12422                  [(reg FLAGS_REG) (const_int 0)])
12423             (const_int 0)))]
12424   ""
12425   [(set (match_dup 0) (match_dup 1))]
12427   rtx new_op1 = copy_rtx (operands[1]);
12428   operands[1] = new_op1;
12429   PUT_MODE (new_op1, QImode);
12430   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12431                                              GET_MODE (XEXP (new_op1, 0))));
12433   /* Make sure that (a) the CCmode we have for the flags is strong
12434      enough for the reversed compare or (b) we have a valid FP compare.  */
12435   if (! ix86_comparison_operator (new_op1, VOIDmode))
12436     FAIL;
12439 (define_split 
12440   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12441         (eq:QI (match_operator 1 "ix86_comparison_operator"
12442                  [(reg FLAGS_REG) (const_int 0)])
12443             (const_int 0)))]
12444   ""
12445   [(set (match_dup 0) (match_dup 1))]
12447   rtx new_op1 = copy_rtx (operands[1]);
12448   operands[1] = new_op1;
12449   PUT_MODE (new_op1, QImode);
12450   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12451                                              GET_MODE (XEXP (new_op1, 0))));
12453   /* Make sure that (a) the CCmode we have for the flags is strong
12454      enough for the reversed compare or (b) we have a valid FP compare.  */
12455   if (! ix86_comparison_operator (new_op1, VOIDmode))
12456     FAIL;
12459 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12460 ;; subsequent logical operations are used to imitate conditional moves.
12461 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12462 ;; it directly.
12464 (define_insn "*sse_setccsf"
12465   [(set (match_operand:SF 0 "register_operand" "=x")
12466         (match_operator:SF 1 "sse_comparison_operator"
12467           [(match_operand:SF 2 "register_operand" "0")
12468            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12469   "TARGET_SSE"
12470   "cmp%D1ss\t{%3, %0|%0, %3}"
12471   [(set_attr "type" "ssecmp")
12472    (set_attr "mode" "SF")])
12474 (define_insn "*sse_setccdf"
12475   [(set (match_operand:DF 0 "register_operand" "=Y")
12476         (match_operator:DF 1 "sse_comparison_operator"
12477           [(match_operand:DF 2 "register_operand" "0")
12478            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12479   "TARGET_SSE2"
12480   "cmp%D1sd\t{%3, %0|%0, %3}"
12481   [(set_attr "type" "ssecmp")
12482    (set_attr "mode" "DF")])
12484 ;; Basic conditional jump instructions.
12485 ;; We ignore the overflow flag for signed branch instructions.
12487 ;; For all bCOND expanders, also expand the compare or test insn that
12488 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12490 (define_expand "beq"
12491   [(set (pc)
12492         (if_then_else (match_dup 1)
12493                       (label_ref (match_operand 0 "" ""))
12494                       (pc)))]
12495   ""
12496   "ix86_expand_branch (EQ, operands[0]); DONE;")
12498 (define_expand "bne"
12499   [(set (pc)
12500         (if_then_else (match_dup 1)
12501                       (label_ref (match_operand 0 "" ""))
12502                       (pc)))]
12503   ""
12504   "ix86_expand_branch (NE, operands[0]); DONE;")
12506 (define_expand "bgt"
12507   [(set (pc)
12508         (if_then_else (match_dup 1)
12509                       (label_ref (match_operand 0 "" ""))
12510                       (pc)))]
12511   ""
12512   "ix86_expand_branch (GT, operands[0]); DONE;")
12514 (define_expand "bgtu"
12515   [(set (pc)
12516         (if_then_else (match_dup 1)
12517                       (label_ref (match_operand 0 "" ""))
12518                       (pc)))]
12519   ""
12520   "ix86_expand_branch (GTU, operands[0]); DONE;")
12522 (define_expand "blt"
12523   [(set (pc)
12524         (if_then_else (match_dup 1)
12525                       (label_ref (match_operand 0 "" ""))
12526                       (pc)))]
12527   ""
12528   "ix86_expand_branch (LT, operands[0]); DONE;")
12530 (define_expand "bltu"
12531   [(set (pc)
12532         (if_then_else (match_dup 1)
12533                       (label_ref (match_operand 0 "" ""))
12534                       (pc)))]
12535   ""
12536   "ix86_expand_branch (LTU, operands[0]); DONE;")
12538 (define_expand "bge"
12539   [(set (pc)
12540         (if_then_else (match_dup 1)
12541                       (label_ref (match_operand 0 "" ""))
12542                       (pc)))]
12543   ""
12544   "ix86_expand_branch (GE, operands[0]); DONE;")
12546 (define_expand "bgeu"
12547   [(set (pc)
12548         (if_then_else (match_dup 1)
12549                       (label_ref (match_operand 0 "" ""))
12550                       (pc)))]
12551   ""
12552   "ix86_expand_branch (GEU, operands[0]); DONE;")
12554 (define_expand "ble"
12555   [(set (pc)
12556         (if_then_else (match_dup 1)
12557                       (label_ref (match_operand 0 "" ""))
12558                       (pc)))]
12559   ""
12560   "ix86_expand_branch (LE, operands[0]); DONE;")
12562 (define_expand "bleu"
12563   [(set (pc)
12564         (if_then_else (match_dup 1)
12565                       (label_ref (match_operand 0 "" ""))
12566                       (pc)))]
12567   ""
12568   "ix86_expand_branch (LEU, operands[0]); DONE;")
12570 (define_expand "bunordered"
12571   [(set (pc)
12572         (if_then_else (match_dup 1)
12573                       (label_ref (match_operand 0 "" ""))
12574                       (pc)))]
12575   "TARGET_80387 || TARGET_SSE_MATH"
12576   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12578 (define_expand "bordered"
12579   [(set (pc)
12580         (if_then_else (match_dup 1)
12581                       (label_ref (match_operand 0 "" ""))
12582                       (pc)))]
12583   "TARGET_80387 || TARGET_SSE_MATH"
12584   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12586 (define_expand "buneq"
12587   [(set (pc)
12588         (if_then_else (match_dup 1)
12589                       (label_ref (match_operand 0 "" ""))
12590                       (pc)))]
12591   "TARGET_80387 || TARGET_SSE_MATH"
12592   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12594 (define_expand "bunge"
12595   [(set (pc)
12596         (if_then_else (match_dup 1)
12597                       (label_ref (match_operand 0 "" ""))
12598                       (pc)))]
12599   "TARGET_80387 || TARGET_SSE_MATH"
12600   "ix86_expand_branch (UNGE, operands[0]); DONE;")
12602 (define_expand "bungt"
12603   [(set (pc)
12604         (if_then_else (match_dup 1)
12605                       (label_ref (match_operand 0 "" ""))
12606                       (pc)))]
12607   "TARGET_80387 || TARGET_SSE_MATH"
12608   "ix86_expand_branch (UNGT, operands[0]); DONE;")
12610 (define_expand "bunle"
12611   [(set (pc)
12612         (if_then_else (match_dup 1)
12613                       (label_ref (match_operand 0 "" ""))
12614                       (pc)))]
12615   "TARGET_80387 || TARGET_SSE_MATH"
12616   "ix86_expand_branch (UNLE, operands[0]); DONE;")
12618 (define_expand "bunlt"
12619   [(set (pc)
12620         (if_then_else (match_dup 1)
12621                       (label_ref (match_operand 0 "" ""))
12622                       (pc)))]
12623   "TARGET_80387 || TARGET_SSE_MATH"
12624   "ix86_expand_branch (UNLT, operands[0]); DONE;")
12626 (define_expand "bltgt"
12627   [(set (pc)
12628         (if_then_else (match_dup 1)
12629                       (label_ref (match_operand 0 "" ""))
12630                       (pc)))]
12631   "TARGET_80387 || TARGET_SSE_MATH"
12632   "ix86_expand_branch (LTGT, operands[0]); DONE;")
12634 (define_insn "*jcc_1"
12635   [(set (pc)
12636         (if_then_else (match_operator 1 "ix86_comparison_operator"
12637                                       [(reg FLAGS_REG) (const_int 0)])
12638                       (label_ref (match_operand 0 "" ""))
12639                       (pc)))]
12640   ""
12641   "%+j%C1\t%l0"
12642   [(set_attr "type" "ibr")
12643    (set_attr "modrm" "0")
12644    (set (attr "length")
12645            (if_then_else (and (ge (minus (match_dup 0) (pc))
12646                                   (const_int -126))
12647                               (lt (minus (match_dup 0) (pc))
12648                                   (const_int 128)))
12649              (const_int 2)
12650              (const_int 6)))])
12652 (define_insn "*jcc_2"
12653   [(set (pc)
12654         (if_then_else (match_operator 1 "ix86_comparison_operator"
12655                                       [(reg FLAGS_REG) (const_int 0)])
12656                       (pc)
12657                       (label_ref (match_operand 0 "" ""))))]
12658   ""
12659   "%+j%c1\t%l0"
12660   [(set_attr "type" "ibr")
12661    (set_attr "modrm" "0")
12662    (set (attr "length")
12663            (if_then_else (and (ge (minus (match_dup 0) (pc))
12664                                   (const_int -126))
12665                               (lt (minus (match_dup 0) (pc))
12666                                   (const_int 128)))
12667              (const_int 2)
12668              (const_int 6)))])
12670 ;; In general it is not safe to assume too much about CCmode registers,
12671 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12672 ;; conditions this is safe on x86, so help combine not create
12674 ;;      seta    %al
12675 ;;      testb   %al, %al
12676 ;;      je      Lfoo
12678 (define_split 
12679   [(set (pc)
12680         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12681                                       [(reg FLAGS_REG) (const_int 0)])
12682                           (const_int 0))
12683                       (label_ref (match_operand 1 "" ""))
12684                       (pc)))]
12685   ""
12686   [(set (pc)
12687         (if_then_else (match_dup 0)
12688                       (label_ref (match_dup 1))
12689                       (pc)))]
12691   PUT_MODE (operands[0], VOIDmode);
12693   
12694 (define_split 
12695   [(set (pc)
12696         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12697                                       [(reg FLAGS_REG) (const_int 0)])
12698                           (const_int 0))
12699                       (label_ref (match_operand 1 "" ""))
12700                       (pc)))]
12701   ""
12702   [(set (pc)
12703         (if_then_else (match_dup 0)
12704                       (label_ref (match_dup 1))
12705                       (pc)))]
12707   rtx new_op0 = copy_rtx (operands[0]);
12708   operands[0] = new_op0;
12709   PUT_MODE (new_op0, VOIDmode);
12710   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12711                                              GET_MODE (XEXP (new_op0, 0))));
12713   /* Make sure that (a) the CCmode we have for the flags is strong
12714      enough for the reversed compare or (b) we have a valid FP compare.  */
12715   if (! ix86_comparison_operator (new_op0, VOIDmode))
12716     FAIL;
12719 ;; Define combination compare-and-branch fp compare instructions to use
12720 ;; during early optimization.  Splitting the operation apart early makes
12721 ;; for bad code when we want to reverse the operation.
12723 (define_insn "*fp_jcc_1_mixed"
12724   [(set (pc)
12725         (if_then_else (match_operator 0 "comparison_operator"
12726                         [(match_operand 1 "register_operand" "f#x,x#f")
12727                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12728           (label_ref (match_operand 3 "" ""))
12729           (pc)))
12730    (clobber (reg:CCFP FPSR_REG))
12731    (clobber (reg:CCFP FLAGS_REG))]
12732   "TARGET_MIX_SSE_I387
12733    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12734    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12735    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12736   "#")
12738 (define_insn "*fp_jcc_1_sse"
12739   [(set (pc)
12740         (if_then_else (match_operator 0 "comparison_operator"
12741                         [(match_operand 1 "register_operand" "x")
12742                          (match_operand 2 "nonimmediate_operand" "xm")])
12743           (label_ref (match_operand 3 "" ""))
12744           (pc)))
12745    (clobber (reg:CCFP FPSR_REG))
12746    (clobber (reg:CCFP FLAGS_REG))]
12747   "TARGET_SSE_MATH
12748    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12749    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12750    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12751   "#")
12753 (define_insn "*fp_jcc_1_387"
12754   [(set (pc)
12755         (if_then_else (match_operator 0 "comparison_operator"
12756                         [(match_operand 1 "register_operand" "f")
12757                          (match_operand 2 "register_operand" "f")])
12758           (label_ref (match_operand 3 "" ""))
12759           (pc)))
12760    (clobber (reg:CCFP FPSR_REG))
12761    (clobber (reg:CCFP FLAGS_REG))]
12762   "TARGET_CMOVE && TARGET_80387
12763    && FLOAT_MODE_P (GET_MODE (operands[1]))
12764    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12765    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12766   "#")
12768 (define_insn "*fp_jcc_2_mixed"
12769   [(set (pc)
12770         (if_then_else (match_operator 0 "comparison_operator"
12771                         [(match_operand 1 "register_operand" "f#x,x#f")
12772                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12773           (pc)
12774           (label_ref (match_operand 3 "" ""))))
12775    (clobber (reg:CCFP FPSR_REG))
12776    (clobber (reg:CCFP FLAGS_REG))]
12777   "TARGET_MIX_SSE_I387
12778    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12779    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12780    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12781   "#")
12783 (define_insn "*fp_jcc_2_sse"
12784   [(set (pc)
12785         (if_then_else (match_operator 0 "comparison_operator"
12786                         [(match_operand 1 "register_operand" "x")
12787                          (match_operand 2 "nonimmediate_operand" "xm")])
12788           (pc)
12789           (label_ref (match_operand 3 "" ""))))
12790    (clobber (reg:CCFP FPSR_REG))
12791    (clobber (reg:CCFP FLAGS_REG))]
12792   "TARGET_SSE_MATH
12793    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12794    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12795    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12796   "#")
12798 (define_insn "*fp_jcc_2_387"
12799   [(set (pc)
12800         (if_then_else (match_operator 0 "comparison_operator"
12801                         [(match_operand 1 "register_operand" "f")
12802                          (match_operand 2 "register_operand" "f")])
12803           (pc)
12804           (label_ref (match_operand 3 "" ""))))
12805    (clobber (reg:CCFP FPSR_REG))
12806    (clobber (reg:CCFP FLAGS_REG))]
12807   "TARGET_CMOVE && TARGET_80387
12808    && FLOAT_MODE_P (GET_MODE (operands[1]))
12809    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12810    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12811   "#")
12813 (define_insn "*fp_jcc_3_387"
12814   [(set (pc)
12815         (if_then_else (match_operator 0 "comparison_operator"
12816                         [(match_operand 1 "register_operand" "f")
12817                          (match_operand 2 "nonimmediate_operand" "fm")])
12818           (label_ref (match_operand 3 "" ""))
12819           (pc)))
12820    (clobber (reg:CCFP FPSR_REG))
12821    (clobber (reg:CCFP FLAGS_REG))
12822    (clobber (match_scratch:HI 4 "=a"))]
12823   "TARGET_80387
12824    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12825    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12826    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12827    && SELECT_CC_MODE (GET_CODE (operands[0]),
12828                       operands[1], operands[2]) == CCFPmode
12829    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12830   "#")
12832 (define_insn "*fp_jcc_4_387"
12833   [(set (pc)
12834         (if_then_else (match_operator 0 "comparison_operator"
12835                         [(match_operand 1 "register_operand" "f")
12836                          (match_operand 2 "nonimmediate_operand" "fm")])
12837           (pc)
12838           (label_ref (match_operand 3 "" ""))))
12839    (clobber (reg:CCFP FPSR_REG))
12840    (clobber (reg:CCFP FLAGS_REG))
12841    (clobber (match_scratch:HI 4 "=a"))]
12842   "TARGET_80387
12843    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12844    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12845    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12846    && SELECT_CC_MODE (GET_CODE (operands[0]),
12847                       operands[1], operands[2]) == CCFPmode
12848    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12849   "#")
12851 (define_insn "*fp_jcc_5_387"
12852   [(set (pc)
12853         (if_then_else (match_operator 0 "comparison_operator"
12854                         [(match_operand 1 "register_operand" "f")
12855                          (match_operand 2 "register_operand" "f")])
12856           (label_ref (match_operand 3 "" ""))
12857           (pc)))
12858    (clobber (reg:CCFP FPSR_REG))
12859    (clobber (reg:CCFP FLAGS_REG))
12860    (clobber (match_scratch:HI 4 "=a"))]
12861   "TARGET_80387
12862    && FLOAT_MODE_P (GET_MODE (operands[1]))
12863    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12864    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12865   "#")
12867 (define_insn "*fp_jcc_6_387"
12868   [(set (pc)
12869         (if_then_else (match_operator 0 "comparison_operator"
12870                         [(match_operand 1 "register_operand" "f")
12871                          (match_operand 2 "register_operand" "f")])
12872           (pc)
12873           (label_ref (match_operand 3 "" ""))))
12874    (clobber (reg:CCFP FPSR_REG))
12875    (clobber (reg:CCFP FLAGS_REG))
12876    (clobber (match_scratch:HI 4 "=a"))]
12877   "TARGET_80387
12878    && FLOAT_MODE_P (GET_MODE (operands[1]))
12879    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12880    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12881   "#")
12883 (define_insn "*fp_jcc_7_387"
12884   [(set (pc)
12885         (if_then_else (match_operator 0 "comparison_operator"
12886                         [(match_operand 1 "register_operand" "f")
12887                          (match_operand 2 "const0_operand" "X")])
12888           (label_ref (match_operand 3 "" ""))
12889           (pc)))
12890    (clobber (reg:CCFP FPSR_REG))
12891    (clobber (reg:CCFP FLAGS_REG))
12892    (clobber (match_scratch:HI 4 "=a"))]
12893   "TARGET_80387
12894    && FLOAT_MODE_P (GET_MODE (operands[1]))
12895    && GET_MODE (operands[1]) == GET_MODE (operands[2])
12896    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12897    && SELECT_CC_MODE (GET_CODE (operands[0]),
12898                       operands[1], operands[2]) == CCFPmode
12899    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12900   "#")
12902 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12903 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12904 ;; with a precedence over other operators and is always put in the first
12905 ;; place. Swap condition and operands to match ficom instruction.
12907 (define_insn "*fp_jcc_8<mode>_387"
12908   [(set (pc)
12909         (if_then_else (match_operator 0 "comparison_operator"
12910                         [(match_operator 1 "float_operator"
12911                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12912                            (match_operand 3 "register_operand" "f,f")])
12913           (label_ref (match_operand 4 "" ""))
12914           (pc)))
12915    (clobber (reg:CCFP FPSR_REG))
12916    (clobber (reg:CCFP FLAGS_REG))
12917    (clobber (match_scratch:HI 5 "=a,a"))]
12918   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
12919    && FLOAT_MODE_P (GET_MODE (operands[3]))
12920    && GET_MODE (operands[1]) == GET_MODE (operands[3])
12921    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12922    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12923    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12924   "#")
12926 (define_split
12927   [(set (pc)
12928         (if_then_else (match_operator 0 "comparison_operator"
12929                         [(match_operand 1 "register_operand" "")
12930                          (match_operand 2 "nonimmediate_operand" "")])
12931           (match_operand 3 "" "")
12932           (match_operand 4 "" "")))
12933    (clobber (reg:CCFP FPSR_REG))
12934    (clobber (reg:CCFP FLAGS_REG))]
12935   "reload_completed"
12936   [(const_int 0)]
12938   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12939                         operands[3], operands[4], NULL_RTX, NULL_RTX);
12940   DONE;
12943 (define_split
12944   [(set (pc)
12945         (if_then_else (match_operator 0 "comparison_operator"
12946                         [(match_operand 1 "register_operand" "")
12947                          (match_operand 2 "general_operand" "")])
12948           (match_operand 3 "" "")
12949           (match_operand 4 "" "")))
12950    (clobber (reg:CCFP FPSR_REG))
12951    (clobber (reg:CCFP FLAGS_REG))
12952    (clobber (match_scratch:HI 5 "=a"))]
12953   "reload_completed"
12954   [(const_int 0)]
12956   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12957                         operands[3], operands[4], operands[5], NULL_RTX);
12958   DONE;
12961 (define_split
12962   [(set (pc)
12963         (if_then_else (match_operator 0 "comparison_operator"
12964                         [(match_operator 1 "float_operator"
12965                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
12966                            (match_operand 3 "register_operand" "")])
12967           (match_operand 4 "" "")
12968           (match_operand 5 "" "")))
12969    (clobber (reg:CCFP FPSR_REG))
12970    (clobber (reg:CCFP FLAGS_REG))
12971    (clobber (match_scratch:HI 6 "=a"))]
12972   "reload_completed"
12973   [(const_int 0)]
12975   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12976   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12977                         operands[3], operands[7],
12978                         operands[4], operands[5], operands[6], NULL_RTX);
12979   DONE;
12982 ;; %%% Kill this when reload knows how to do it.
12983 (define_split
12984   [(set (pc)
12985         (if_then_else (match_operator 0 "comparison_operator"
12986                         [(match_operator 1 "float_operator"
12987                            [(match_operand:X87MODEI12 2 "register_operand" "")])
12988                            (match_operand 3 "register_operand" "")])
12989           (match_operand 4 "" "")
12990           (match_operand 5 "" "")))
12991    (clobber (reg:CCFP FPSR_REG))
12992    (clobber (reg:CCFP FLAGS_REG))
12993    (clobber (match_scratch:HI 6 "=a"))]
12994   "reload_completed"
12995   [(const_int 0)]
12997   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12998   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
12999   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13000                         operands[3], operands[7],
13001                         operands[4], operands[5], operands[6], operands[2]);
13002   DONE;
13005 ;; Unconditional and other jump instructions
13007 (define_insn "jump"
13008   [(set (pc)
13009         (label_ref (match_operand 0 "" "")))]
13010   ""
13011   "jmp\t%l0"
13012   [(set_attr "type" "ibr")
13013    (set (attr "length")
13014            (if_then_else (and (ge (minus (match_dup 0) (pc))
13015                                   (const_int -126))
13016                               (lt (minus (match_dup 0) (pc))
13017                                   (const_int 128)))
13018              (const_int 2)
13019              (const_int 5)))
13020    (set_attr "modrm" "0")])
13022 (define_expand "indirect_jump"
13023   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13024   ""
13025   "")
13027 (define_insn "*indirect_jump"
13028   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13029   "!TARGET_64BIT"
13030   "jmp\t%A0"
13031   [(set_attr "type" "ibr")
13032    (set_attr "length_immediate" "0")])
13034 (define_insn "*indirect_jump_rtx64"
13035   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13036   "TARGET_64BIT"
13037   "jmp\t%A0"
13038   [(set_attr "type" "ibr")
13039    (set_attr "length_immediate" "0")])
13041 (define_expand "tablejump"
13042   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13043               (use (label_ref (match_operand 1 "" "")))])]
13044   ""
13046   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13047      relative.  Convert the relative address to an absolute address.  */
13048   if (flag_pic)
13049     {
13050       rtx op0, op1;
13051       enum rtx_code code;
13053       if (TARGET_64BIT)
13054         {
13055           code = PLUS;
13056           op0 = operands[0];
13057           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13058         }
13059       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13060         {
13061           code = PLUS;
13062           op0 = operands[0];
13063           op1 = pic_offset_table_rtx;
13064         }
13065       else
13066         {
13067           code = MINUS;
13068           op0 = pic_offset_table_rtx;
13069           op1 = operands[0];
13070         }
13072       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13073                                          OPTAB_DIRECT);
13074     }
13077 (define_insn "*tablejump_1"
13078   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13079    (use (label_ref (match_operand 1 "" "")))]
13080   "!TARGET_64BIT"
13081   "jmp\t%A0"
13082   [(set_attr "type" "ibr")
13083    (set_attr "length_immediate" "0")])
13085 (define_insn "*tablejump_1_rtx64"
13086   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13087    (use (label_ref (match_operand 1 "" "")))]
13088   "TARGET_64BIT"
13089   "jmp\t%A0"
13090   [(set_attr "type" "ibr")
13091    (set_attr "length_immediate" "0")])
13093 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13095 (define_peephole2
13096   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13097    (set (match_operand:QI 1 "register_operand" "")
13098         (match_operator:QI 2 "ix86_comparison_operator"
13099           [(reg FLAGS_REG) (const_int 0)]))
13100    (set (match_operand 3 "q_regs_operand" "")
13101         (zero_extend (match_dup 1)))]
13102   "(peep2_reg_dead_p (3, operands[1])
13103     || operands_match_p (operands[1], operands[3]))
13104    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13105   [(set (match_dup 4) (match_dup 0))
13106    (set (strict_low_part (match_dup 5))
13107         (match_dup 2))]
13109   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13110   operands[5] = gen_lowpart (QImode, operands[3]);
13111   ix86_expand_clear (operands[3]);
13114 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13116 (define_peephole2
13117   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13118    (set (match_operand:QI 1 "register_operand" "")
13119         (match_operator:QI 2 "ix86_comparison_operator"
13120           [(reg FLAGS_REG) (const_int 0)]))
13121    (parallel [(set (match_operand 3 "q_regs_operand" "")
13122                    (zero_extend (match_dup 1)))
13123               (clobber (reg:CC FLAGS_REG))])]
13124   "(peep2_reg_dead_p (3, operands[1])
13125     || operands_match_p (operands[1], operands[3]))
13126    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13127   [(set (match_dup 4) (match_dup 0))
13128    (set (strict_low_part (match_dup 5))
13129         (match_dup 2))]
13131   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13132   operands[5] = gen_lowpart (QImode, operands[3]);
13133   ix86_expand_clear (operands[3]);
13136 ;; Call instructions.
13138 ;; The predicates normally associated with named expanders are not properly
13139 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13140 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13142 ;; Call subroutine returning no value.
13144 (define_expand "call_pop"
13145   [(parallel [(call (match_operand:QI 0 "" "")
13146                     (match_operand:SI 1 "" ""))
13147               (set (reg:SI SP_REG)
13148                    (plus:SI (reg:SI SP_REG)
13149                             (match_operand:SI 3 "" "")))])]
13150   "!TARGET_64BIT"
13152   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13153   DONE;
13156 (define_insn "*call_pop_0"
13157   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13158          (match_operand:SI 1 "" ""))
13159    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13160                             (match_operand:SI 2 "immediate_operand" "")))]
13161   "!TARGET_64BIT"
13163   if (SIBLING_CALL_P (insn))
13164     return "jmp\t%P0";
13165   else
13166     return "call\t%P0";
13168   [(set_attr "type" "call")])
13169   
13170 (define_insn "*call_pop_1"
13171   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13172          (match_operand:SI 1 "" ""))
13173    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13174                             (match_operand:SI 2 "immediate_operand" "i")))]
13175   "!TARGET_64BIT"
13177   if (constant_call_address_operand (operands[0], Pmode))
13178     {
13179       if (SIBLING_CALL_P (insn))
13180         return "jmp\t%P0";
13181       else
13182         return "call\t%P0";
13183     }
13184   if (SIBLING_CALL_P (insn))
13185     return "jmp\t%A0";
13186   else
13187     return "call\t%A0";
13189   [(set_attr "type" "call")])
13191 (define_expand "call"
13192   [(call (match_operand:QI 0 "" "")
13193          (match_operand 1 "" ""))
13194    (use (match_operand 2 "" ""))]
13195   ""
13197   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13198   DONE;
13201 (define_expand "sibcall"
13202   [(call (match_operand:QI 0 "" "")
13203          (match_operand 1 "" ""))
13204    (use (match_operand 2 "" ""))]
13205   ""
13207   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13208   DONE;
13211 (define_insn "*call_0"
13212   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13213          (match_operand 1 "" ""))]
13214   ""
13216   if (SIBLING_CALL_P (insn))
13217     return "jmp\t%P0";
13218   else
13219     return "call\t%P0";
13221   [(set_attr "type" "call")])
13223 (define_insn "*call_1"
13224   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13225          (match_operand 1 "" ""))]
13226   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13228   if (constant_call_address_operand (operands[0], Pmode))
13229     return "call\t%P0";
13230   return "call\t%A0";
13232   [(set_attr "type" "call")])
13234 (define_insn "*sibcall_1"
13235   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13236          (match_operand 1 "" ""))]
13237   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13239   if (constant_call_address_operand (operands[0], Pmode))
13240     return "jmp\t%P0";
13241   return "jmp\t%A0";
13243   [(set_attr "type" "call")])
13245 (define_insn "*call_1_rex64"
13246   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13247          (match_operand 1 "" ""))]
13248   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13250   if (constant_call_address_operand (operands[0], Pmode))
13251     return "call\t%P0";
13252   return "call\t%A0";
13254   [(set_attr "type" "call")])
13256 (define_insn "*sibcall_1_rex64"
13257   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13258          (match_operand 1 "" ""))]
13259   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13260   "jmp\t%P0"
13261   [(set_attr "type" "call")])
13263 (define_insn "*sibcall_1_rex64_v"
13264   [(call (mem:QI (reg:DI 40))
13265          (match_operand 0 "" ""))]
13266   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13267   "jmp\t*%%r11"
13268   [(set_attr "type" "call")])
13271 ;; Call subroutine, returning value in operand 0
13273 (define_expand "call_value_pop"
13274   [(parallel [(set (match_operand 0 "" "")
13275                    (call (match_operand:QI 1 "" "")
13276                          (match_operand:SI 2 "" "")))
13277               (set (reg:SI SP_REG)
13278                    (plus:SI (reg:SI SP_REG)
13279                             (match_operand:SI 4 "" "")))])]
13280   "!TARGET_64BIT"
13282   ix86_expand_call (operands[0], operands[1], operands[2],
13283                     operands[3], operands[4], 0);
13284   DONE;
13287 (define_expand "call_value"
13288   [(set (match_operand 0 "" "")
13289         (call (match_operand:QI 1 "" "")
13290               (match_operand:SI 2 "" "")))
13291    (use (match_operand:SI 3 "" ""))]
13292   ;; Operand 2 not used on the i386.
13293   ""
13295   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13296   DONE;
13299 (define_expand "sibcall_value"
13300   [(set (match_operand 0 "" "")
13301         (call (match_operand:QI 1 "" "")
13302               (match_operand:SI 2 "" "")))
13303    (use (match_operand:SI 3 "" ""))]
13304   ;; Operand 2 not used on the i386.
13305   ""
13307   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13308   DONE;
13311 ;; Call subroutine returning any type.
13313 (define_expand "untyped_call"
13314   [(parallel [(call (match_operand 0 "" "")
13315                     (const_int 0))
13316               (match_operand 1 "" "")
13317               (match_operand 2 "" "")])]
13318   ""
13320   int i;
13322   /* In order to give reg-stack an easier job in validating two
13323      coprocessor registers as containing a possible return value,
13324      simply pretend the untyped call returns a complex long double
13325      value.  */
13327   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13328                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13329                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13330                     NULL, 0);
13332   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13333     {
13334       rtx set = XVECEXP (operands[2], 0, i);
13335       emit_move_insn (SET_DEST (set), SET_SRC (set));
13336     }
13338   /* The optimizer does not know that the call sets the function value
13339      registers we stored in the result block.  We avoid problems by
13340      claiming that all hard registers are used and clobbered at this
13341      point.  */
13342   emit_insn (gen_blockage (const0_rtx));
13344   DONE;
13347 ;; Prologue and epilogue instructions
13349 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13350 ;; all of memory.  This blocks insns from being moved across this point.
13352 (define_insn "blockage"
13353   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13354   ""
13355   ""
13356   [(set_attr "length" "0")])
13358 ;; Insn emitted into the body of a function to return from a function.
13359 ;; This is only done if the function's epilogue is known to be simple.
13360 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13362 (define_expand "return"
13363   [(return)]
13364   "ix86_can_use_return_insn_p ()"
13366   if (current_function_pops_args)
13367     {
13368       rtx popc = GEN_INT (current_function_pops_args);
13369       emit_jump_insn (gen_return_pop_internal (popc));
13370       DONE;
13371     }
13374 (define_insn "return_internal"
13375   [(return)]
13376   "reload_completed"
13377   "ret"
13378   [(set_attr "length" "1")
13379    (set_attr "length_immediate" "0")
13380    (set_attr "modrm" "0")])
13382 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13383 ;; instruction Athlon and K8 have.
13385 (define_insn "return_internal_long"
13386   [(return)
13387    (unspec [(const_int 0)] UNSPEC_REP)]
13388   "reload_completed"
13389   "rep {;} ret"
13390   [(set_attr "length" "1")
13391    (set_attr "length_immediate" "0")
13392    (set_attr "prefix_rep" "1")
13393    (set_attr "modrm" "0")])
13395 (define_insn "return_pop_internal"
13396   [(return)
13397    (use (match_operand:SI 0 "const_int_operand" ""))]
13398   "reload_completed"
13399   "ret\t%0"
13400   [(set_attr "length" "3")
13401    (set_attr "length_immediate" "2")
13402    (set_attr "modrm" "0")])
13404 (define_insn "return_indirect_internal"
13405   [(return)
13406    (use (match_operand:SI 0 "register_operand" "r"))]
13407   "reload_completed"
13408   "jmp\t%A0"
13409   [(set_attr "type" "ibr")
13410    (set_attr "length_immediate" "0")])
13412 (define_insn "nop"
13413   [(const_int 0)]
13414   ""
13415   "nop"
13416   [(set_attr "length" "1")
13417    (set_attr "length_immediate" "0")
13418    (set_attr "modrm" "0")])
13420 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13421 ;; branch prediction penalty for the third jump in a 16-byte
13422 ;; block on K8.
13424 (define_insn "align"
13425   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13426   ""
13428 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13429   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13430 #else
13431   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13432      The align insn is used to avoid 3 jump instructions in the row to improve
13433      branch prediction and the benefits hardly outweight the cost of extra 8
13434      nops on the average inserted by full alignment pseudo operation.  */
13435 #endif
13436   return "";
13438   [(set_attr "length" "16")])
13440 (define_expand "prologue"
13441   [(const_int 1)]
13442   ""
13443   "ix86_expand_prologue (); DONE;")
13445 (define_insn "set_got"
13446   [(set (match_operand:SI 0 "register_operand" "=r")
13447         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13448    (clobber (reg:CC FLAGS_REG))]
13449   "!TARGET_64BIT"
13450   { return output_set_got (operands[0]); }
13451   [(set_attr "type" "multi")
13452    (set_attr "length" "12")])
13454 (define_expand "epilogue"
13455   [(const_int 1)]
13456   ""
13457   "ix86_expand_epilogue (1); DONE;")
13459 (define_expand "sibcall_epilogue"
13460   [(const_int 1)]
13461   ""
13462   "ix86_expand_epilogue (0); DONE;")
13464 (define_expand "eh_return"
13465   [(use (match_operand 0 "register_operand" ""))]
13466   ""
13468   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13470   /* Tricky bit: we write the address of the handler to which we will
13471      be returning into someone else's stack frame, one word below the
13472      stack address we wish to restore.  */
13473   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13474   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13475   tmp = gen_rtx_MEM (Pmode, tmp);
13476   emit_move_insn (tmp, ra);
13478   if (Pmode == SImode)
13479     emit_jump_insn (gen_eh_return_si (sa));
13480   else
13481     emit_jump_insn (gen_eh_return_di (sa));
13482   emit_barrier ();
13483   DONE;
13486 (define_insn_and_split "eh_return_si"
13487   [(set (pc) 
13488         (unspec [(match_operand:SI 0 "register_operand" "c")]
13489                  UNSPEC_EH_RETURN))]
13490   "!TARGET_64BIT"
13491   "#"
13492   "reload_completed"
13493   [(const_int 1)]
13494   "ix86_expand_epilogue (2); DONE;")
13496 (define_insn_and_split "eh_return_di"
13497   [(set (pc) 
13498         (unspec [(match_operand:DI 0 "register_operand" "c")]
13499                  UNSPEC_EH_RETURN))]
13500   "TARGET_64BIT"
13501   "#"
13502   "reload_completed"
13503   [(const_int 1)]
13504   "ix86_expand_epilogue (2); DONE;")
13506 (define_insn "leave"
13507   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13508    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13509    (clobber (mem:BLK (scratch)))]
13510   "!TARGET_64BIT"
13511   "leave"
13512   [(set_attr "type" "leave")])
13514 (define_insn "leave_rex64"
13515   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13516    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13517    (clobber (mem:BLK (scratch)))]
13518   "TARGET_64BIT"
13519   "leave"
13520   [(set_attr "type" "leave")])
13522 (define_expand "ffssi2"
13523   [(parallel
13524      [(set (match_operand:SI 0 "register_operand" "") 
13525            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13526       (clobber (match_scratch:SI 2 ""))
13527       (clobber (reg:CC FLAGS_REG))])]
13528   ""
13529   "")
13531 (define_insn_and_split "*ffs_cmove"
13532   [(set (match_operand:SI 0 "register_operand" "=r") 
13533         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13534    (clobber (match_scratch:SI 2 "=&r"))
13535    (clobber (reg:CC FLAGS_REG))]
13536   "TARGET_CMOVE"
13537   "#"
13538   "&& reload_completed"
13539   [(set (match_dup 2) (const_int -1))
13540    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13541               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13542    (set (match_dup 0) (if_then_else:SI
13543                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13544                         (match_dup 2)
13545                         (match_dup 0)))
13546    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13547               (clobber (reg:CC FLAGS_REG))])]
13548   "")
13550 (define_insn_and_split "*ffs_no_cmove"
13551   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
13552         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13553    (clobber (match_scratch:SI 2 "=&q"))
13554    (clobber (reg:CC FLAGS_REG))]
13555   ""
13556   "#"
13557   "reload_completed"
13558   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13559               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13560    (set (strict_low_part (match_dup 3))
13561         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13562    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13563               (clobber (reg:CC FLAGS_REG))])
13564    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13565               (clobber (reg:CC FLAGS_REG))])
13566    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13567               (clobber (reg:CC FLAGS_REG))])]
13569   operands[3] = gen_lowpart (QImode, operands[2]);
13570   ix86_expand_clear (operands[2]);
13573 (define_insn "*ffssi_1"
13574   [(set (reg:CCZ FLAGS_REG)
13575         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13576                      (const_int 0)))
13577    (set (match_operand:SI 0 "register_operand" "=r")
13578         (ctz:SI (match_dup 1)))]
13579   ""
13580   "bsf{l}\t{%1, %0|%0, %1}"
13581   [(set_attr "prefix_0f" "1")])
13583 (define_expand "ffsdi2"
13584   [(parallel
13585      [(set (match_operand:DI 0 "register_operand" "") 
13586            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13587       (clobber (match_scratch:DI 2 ""))
13588       (clobber (reg:CC FLAGS_REG))])]
13589   "TARGET_64BIT && TARGET_CMOVE"
13590   "")
13592 (define_insn_and_split "*ffs_rex64"
13593   [(set (match_operand:DI 0 "register_operand" "=r") 
13594         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13595    (clobber (match_scratch:DI 2 "=&r"))
13596    (clobber (reg:CC FLAGS_REG))]
13597   "TARGET_64BIT && TARGET_CMOVE"
13598   "#"
13599   "&& reload_completed"
13600   [(set (match_dup 2) (const_int -1))
13601    (parallel [(set (reg:CCZ FLAGS_REG)
13602                    (compare:CCZ (match_dup 1) (const_int 0)))
13603               (set (match_dup 0) (ctz:DI (match_dup 1)))])
13604    (set (match_dup 0) (if_then_else:DI
13605                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
13606                         (match_dup 2)
13607                         (match_dup 0)))
13608    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13609               (clobber (reg:CC FLAGS_REG))])]
13610   "")
13612 (define_insn "*ffsdi_1"
13613   [(set (reg:CCZ FLAGS_REG)
13614         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13615                      (const_int 0)))
13616    (set (match_operand:DI 0 "register_operand" "=r")
13617         (ctz:DI (match_dup 1)))]
13618   "TARGET_64BIT"
13619   "bsf{q}\t{%1, %0|%0, %1}"
13620   [(set_attr "prefix_0f" "1")])
13622 (define_insn "ctzsi2"
13623   [(set (match_operand:SI 0 "register_operand" "=r")
13624         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13625    (clobber (reg:CC FLAGS_REG))]
13626   ""
13627   "bsf{l}\t{%1, %0|%0, %1}"
13628   [(set_attr "prefix_0f" "1")])
13630 (define_insn "ctzdi2"
13631   [(set (match_operand:DI 0 "register_operand" "=r")
13632         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13633    (clobber (reg:CC FLAGS_REG))]
13634   "TARGET_64BIT"
13635   "bsf{q}\t{%1, %0|%0, %1}"
13636   [(set_attr "prefix_0f" "1")])
13638 (define_expand "clzsi2"
13639   [(parallel
13640      [(set (match_operand:SI 0 "register_operand" "")
13641            (minus:SI (const_int 31)
13642                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13643       (clobber (reg:CC FLAGS_REG))])
13644    (parallel
13645      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13646       (clobber (reg:CC FLAGS_REG))])]
13647   ""
13648   "")
13650 (define_insn "*bsr"
13651   [(set (match_operand:SI 0 "register_operand" "=r")
13652         (minus:SI (const_int 31)
13653                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13654    (clobber (reg:CC FLAGS_REG))]
13655   ""
13656   "bsr{l}\t{%1, %0|%0, %1}"
13657   [(set_attr "prefix_0f" "1")])
13659 (define_expand "clzdi2"
13660   [(parallel
13661      [(set (match_operand:DI 0 "register_operand" "")
13662            (minus:DI (const_int 63)
13663                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13664       (clobber (reg:CC FLAGS_REG))])
13665    (parallel
13666      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13667       (clobber (reg:CC FLAGS_REG))])]
13668   "TARGET_64BIT"
13669   "")
13671 (define_insn "*bsr_rex64"
13672   [(set (match_operand:DI 0 "register_operand" "=r")
13673         (minus:DI (const_int 63)
13674                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13675    (clobber (reg:CC FLAGS_REG))]
13676   "TARGET_64BIT"
13677   "bsr{q}\t{%1, %0|%0, %1}"
13678   [(set_attr "prefix_0f" "1")])
13680 ;; Thread-local storage patterns for ELF.
13682 ;; Note that these code sequences must appear exactly as shown
13683 ;; in order to allow linker relaxation.
13685 (define_insn "*tls_global_dynamic_32_gnu"
13686   [(set (match_operand:SI 0 "register_operand" "=a")
13687         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13688                     (match_operand:SI 2 "tls_symbolic_operand" "")
13689                     (match_operand:SI 3 "call_insn_operand" "")]
13690                     UNSPEC_TLS_GD))
13691    (clobber (match_scratch:SI 4 "=d"))
13692    (clobber (match_scratch:SI 5 "=c"))
13693    (clobber (reg:CC FLAGS_REG))]
13694   "!TARGET_64BIT && TARGET_GNU_TLS"
13695   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13696   [(set_attr "type" "multi")
13697    (set_attr "length" "12")])
13699 (define_insn "*tls_global_dynamic_32_sun"
13700   [(set (match_operand:SI 0 "register_operand" "=a")
13701         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13702                     (match_operand:SI 2 "tls_symbolic_operand" "")
13703                     (match_operand:SI 3 "call_insn_operand" "")]
13704                     UNSPEC_TLS_GD))
13705    (clobber (match_scratch:SI 4 "=d"))
13706    (clobber (match_scratch:SI 5 "=c"))
13707    (clobber (reg:CC FLAGS_REG))]
13708   "!TARGET_64BIT && TARGET_SUN_TLS"
13709   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13710         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13711   [(set_attr "type" "multi")
13712    (set_attr "length" "14")])
13714 (define_expand "tls_global_dynamic_32"
13715   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13716                    (unspec:SI
13717                     [(match_dup 2)
13718                      (match_operand:SI 1 "tls_symbolic_operand" "")
13719                      (match_dup 3)]
13720                     UNSPEC_TLS_GD))
13721               (clobber (match_scratch:SI 4 ""))
13722               (clobber (match_scratch:SI 5 ""))
13723               (clobber (reg:CC FLAGS_REG))])]
13724   ""
13726   if (flag_pic)
13727     operands[2] = pic_offset_table_rtx;
13728   else
13729     {
13730       operands[2] = gen_reg_rtx (Pmode);
13731       emit_insn (gen_set_got (operands[2]));
13732     }
13733   operands[3] = ix86_tls_get_addr ();
13736 (define_insn "*tls_global_dynamic_64"
13737   [(set (match_operand:DI 0 "register_operand" "=a")
13738         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13739                       (match_operand:DI 3 "" "")))
13740    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13741               UNSPEC_TLS_GD)]
13742   "TARGET_64BIT"
13743   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13744   [(set_attr "type" "multi")
13745    (set_attr "length" "16")])
13747 (define_expand "tls_global_dynamic_64"
13748   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13749                    (call (mem:QI (match_dup 2)) (const_int 0)))
13750               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13751                          UNSPEC_TLS_GD)])]
13752   ""
13754   operands[2] = ix86_tls_get_addr ();
13757 (define_insn "*tls_local_dynamic_base_32_gnu"
13758   [(set (match_operand:SI 0 "register_operand" "=a")
13759         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13760                     (match_operand:SI 2 "call_insn_operand" "")]
13761                    UNSPEC_TLS_LD_BASE))
13762    (clobber (match_scratch:SI 3 "=d"))
13763    (clobber (match_scratch:SI 4 "=c"))
13764    (clobber (reg:CC FLAGS_REG))]
13765   "!TARGET_64BIT && TARGET_GNU_TLS"
13766   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13767   [(set_attr "type" "multi")
13768    (set_attr "length" "11")])
13770 (define_insn "*tls_local_dynamic_base_32_sun"
13771   [(set (match_operand:SI 0 "register_operand" "=a")
13772         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13773                     (match_operand:SI 2 "call_insn_operand" "")]
13774                    UNSPEC_TLS_LD_BASE))
13775    (clobber (match_scratch:SI 3 "=d"))
13776    (clobber (match_scratch:SI 4 "=c"))
13777    (clobber (reg:CC FLAGS_REG))]
13778   "!TARGET_64BIT && TARGET_SUN_TLS"
13779   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13780         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13781   [(set_attr "type" "multi")
13782    (set_attr "length" "13")])
13784 (define_expand "tls_local_dynamic_base_32"
13785   [(parallel [(set (match_operand:SI 0 "register_operand" "")
13786                    (unspec:SI [(match_dup 1) (match_dup 2)]
13787                               UNSPEC_TLS_LD_BASE))
13788               (clobber (match_scratch:SI 3 ""))
13789               (clobber (match_scratch:SI 4 ""))
13790               (clobber (reg:CC FLAGS_REG))])]
13791   ""
13793   if (flag_pic)
13794     operands[1] = pic_offset_table_rtx;
13795   else
13796     {
13797       operands[1] = gen_reg_rtx (Pmode);
13798       emit_insn (gen_set_got (operands[1]));
13799     }
13800   operands[2] = ix86_tls_get_addr ();
13803 (define_insn "*tls_local_dynamic_base_64"
13804   [(set (match_operand:DI 0 "register_operand" "=a")
13805         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13806                       (match_operand:DI 2 "" "")))
13807    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13808   "TARGET_64BIT"
13809   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13810   [(set_attr "type" "multi")
13811    (set_attr "length" "12")])
13813 (define_expand "tls_local_dynamic_base_64"
13814   [(parallel [(set (match_operand:DI 0 "register_operand" "")
13815                    (call (mem:QI (match_dup 1)) (const_int 0)))
13816               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13817   ""
13819   operands[1] = ix86_tls_get_addr ();
13822 ;; Local dynamic of a single variable is a lose.  Show combine how
13823 ;; to convert that back to global dynamic.
13825 (define_insn_and_split "*tls_local_dynamic_32_once"
13826   [(set (match_operand:SI 0 "register_operand" "=a")
13827         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13828                              (match_operand:SI 2 "call_insn_operand" "")]
13829                             UNSPEC_TLS_LD_BASE)
13830                  (const:SI (unspec:SI
13831                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
13832                             UNSPEC_DTPOFF))))
13833    (clobber (match_scratch:SI 4 "=d"))
13834    (clobber (match_scratch:SI 5 "=c"))
13835    (clobber (reg:CC FLAGS_REG))]
13836   ""
13837   "#"
13838   ""
13839   [(parallel [(set (match_dup 0)
13840                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13841                               UNSPEC_TLS_GD))
13842               (clobber (match_dup 4))
13843               (clobber (match_dup 5))
13844               (clobber (reg:CC FLAGS_REG))])]
13845   "")
13847 ;; Load and add the thread base pointer from %gs:0.
13849 (define_insn "*load_tp_si"
13850   [(set (match_operand:SI 0 "register_operand" "=r")
13851         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13852   "!TARGET_64BIT"
13853   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13854   [(set_attr "type" "imov")
13855    (set_attr "modrm" "0")
13856    (set_attr "length" "7")
13857    (set_attr "memory" "load")
13858    (set_attr "imm_disp" "false")])
13860 (define_insn "*add_tp_si"
13861   [(set (match_operand:SI 0 "register_operand" "=r")
13862         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13863                  (match_operand:SI 1 "register_operand" "0")))
13864    (clobber (reg:CC FLAGS_REG))]
13865   "!TARGET_64BIT"
13866   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13867   [(set_attr "type" "alu")
13868    (set_attr "modrm" "0")
13869    (set_attr "length" "7")
13870    (set_attr "memory" "load")
13871    (set_attr "imm_disp" "false")])
13873 (define_insn "*load_tp_di"
13874   [(set (match_operand:DI 0 "register_operand" "=r")
13875         (unspec:DI [(const_int 0)] UNSPEC_TP))]
13876   "TARGET_64BIT"
13877   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13878   [(set_attr "type" "imov")
13879    (set_attr "modrm" "0")
13880    (set_attr "length" "7")
13881    (set_attr "memory" "load")
13882    (set_attr "imm_disp" "false")])
13884 (define_insn "*add_tp_di"
13885   [(set (match_operand:DI 0 "register_operand" "=r")
13886         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
13887                  (match_operand:DI 1 "register_operand" "0")))
13888    (clobber (reg:CC FLAGS_REG))]
13889   "TARGET_64BIT"
13890   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13891   [(set_attr "type" "alu")
13892    (set_attr "modrm" "0")
13893    (set_attr "length" "7")
13894    (set_attr "memory" "load")
13895    (set_attr "imm_disp" "false")])
13897 ;; These patterns match the binary 387 instructions for addM3, subM3,
13898 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13899 ;; SFmode.  The first is the normal insn, the second the same insn but
13900 ;; with one operand a conversion, and the third the same insn but with
13901 ;; the other operand a conversion.  The conversion may be SFmode or
13902 ;; SImode if the target mode DFmode, but only SImode if the target mode
13903 ;; is SFmode.
13905 ;; Gcc is slightly more smart about handling normal two address instructions
13906 ;; so use special patterns for add and mull.
13908 (define_insn "*fop_sf_comm_mixed"
13909   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
13910         (match_operator:SF 3 "binary_fp_operator"
13911                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
13912                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
13913   "TARGET_MIX_SSE_I387
13914    && COMMUTATIVE_ARITH_P (operands[3])
13915    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13916   "* return output_387_binary_op (insn, operands);"
13917   [(set (attr "type") 
13918         (if_then_else (eq_attr "alternative" "1")
13919            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13920               (const_string "ssemul")
13921               (const_string "sseadd"))
13922            (if_then_else (match_operand:SF 3 "mult_operator" "") 
13923               (const_string "fmul")
13924               (const_string "fop"))))
13925    (set_attr "mode" "SF")])
13927 (define_insn "*fop_sf_comm_sse"
13928   [(set (match_operand:SF 0 "register_operand" "=x")
13929         (match_operator:SF 3 "binary_fp_operator"
13930                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13931                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13932   "TARGET_SSE_MATH
13933    && COMMUTATIVE_ARITH_P (operands[3])
13934    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13935   "* return output_387_binary_op (insn, operands);"
13936   [(set (attr "type") 
13937         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13938            (const_string "ssemul")
13939            (const_string "sseadd")))
13940    (set_attr "mode" "SF")])
13942 (define_insn "*fop_sf_comm_i387"
13943   [(set (match_operand:SF 0 "register_operand" "=f")
13944         (match_operator:SF 3 "binary_fp_operator"
13945                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
13946                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
13947   "TARGET_80387
13948    && COMMUTATIVE_ARITH_P (operands[3])
13949    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13950   "* return output_387_binary_op (insn, operands);"
13951   [(set (attr "type") 
13952         (if_then_else (match_operand:SF 3 "mult_operator" "") 
13953            (const_string "fmul")
13954            (const_string "fop")))
13955    (set_attr "mode" "SF")])
13957 (define_insn "*fop_sf_1_mixed"
13958   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
13959         (match_operator:SF 3 "binary_fp_operator"
13960                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
13961                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
13962   "TARGET_MIX_SSE_I387
13963    && !COMMUTATIVE_ARITH_P (operands[3])
13964    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
13965   "* return output_387_binary_op (insn, operands);"
13966   [(set (attr "type") 
13967         (cond [(and (eq_attr "alternative" "2")
13968                     (match_operand:SF 3 "mult_operator" ""))
13969                  (const_string "ssemul")
13970                (and (eq_attr "alternative" "2")
13971                     (match_operand:SF 3 "div_operator" ""))
13972                  (const_string "ssediv")
13973                (eq_attr "alternative" "2")
13974                  (const_string "sseadd")
13975                (match_operand:SF 3 "mult_operator" "") 
13976                  (const_string "fmul")
13977                (match_operand:SF 3 "div_operator" "") 
13978                  (const_string "fdiv")
13979               ]
13980               (const_string "fop")))
13981    (set_attr "mode" "SF")])
13983 (define_insn "*fop_sf_1_sse"
13984   [(set (match_operand:SF 0 "register_operand" "=x")
13985         (match_operator:SF 3 "binary_fp_operator"
13986                         [(match_operand:SF 1 "register_operand" "0")
13987                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
13988   "TARGET_SSE_MATH
13989    && !COMMUTATIVE_ARITH_P (operands[3])"
13990   "* return output_387_binary_op (insn, operands);"
13991   [(set (attr "type") 
13992         (cond [(match_operand:SF 3 "mult_operator" "")
13993                  (const_string "ssemul")
13994                (match_operand:SF 3 "div_operator" "")
13995                  (const_string "ssediv")
13996               ]
13997               (const_string "sseadd")))
13998    (set_attr "mode" "SF")])
14000 ;; This pattern is not fully shadowed by the pattern above.
14001 (define_insn "*fop_sf_1_i387"
14002   [(set (match_operand:SF 0 "register_operand" "=f,f")
14003         (match_operator:SF 3 "binary_fp_operator"
14004                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14005                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14006   "TARGET_80387 && !TARGET_SSE_MATH
14007    && !COMMUTATIVE_ARITH_P (operands[3])
14008    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14009   "* return output_387_binary_op (insn, operands);"
14010   [(set (attr "type") 
14011         (cond [(match_operand:SF 3 "mult_operator" "") 
14012                  (const_string "fmul")
14013                (match_operand:SF 3 "div_operator" "") 
14014                  (const_string "fdiv")
14015               ]
14016               (const_string "fop")))
14017    (set_attr "mode" "SF")])
14019 ;; ??? Add SSE splitters for these!
14020 (define_insn "*fop_sf_2<mode>_i387"
14021   [(set (match_operand:SF 0 "register_operand" "=f,f")
14022         (match_operator:SF 3 "binary_fp_operator"
14023           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14024            (match_operand:SF 2 "register_operand" "0,0")]))]
14025   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14026   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14027   [(set (attr "type") 
14028         (cond [(match_operand:SF 3 "mult_operator" "") 
14029                  (const_string "fmul")
14030                (match_operand:SF 3 "div_operator" "") 
14031                  (const_string "fdiv")
14032               ]
14033               (const_string "fop")))
14034    (set_attr "fp_int_src" "true")
14035    (set_attr "mode" "<MODE>")])
14037 (define_insn "*fop_sf_3<mode>_i387"
14038   [(set (match_operand:SF 0 "register_operand" "=f,f")
14039         (match_operator:SF 3 "binary_fp_operator"
14040           [(match_operand:SF 1 "register_operand" "0,0")
14041            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14042   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14043   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14044   [(set (attr "type") 
14045         (cond [(match_operand:SF 3 "mult_operator" "") 
14046                  (const_string "fmul")
14047                (match_operand:SF 3 "div_operator" "") 
14048                  (const_string "fdiv")
14049               ]
14050               (const_string "fop")))
14051    (set_attr "fp_int_src" "true")
14052    (set_attr "mode" "<MODE>")])
14054 (define_insn "*fop_df_comm_mixed"
14055   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14056         (match_operator:DF 3 "binary_fp_operator"
14057                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14058                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14059   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14060    && COMMUTATIVE_ARITH_P (operands[3])
14061    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14062   "* return output_387_binary_op (insn, operands);"
14063   [(set (attr "type") 
14064         (if_then_else (eq_attr "alternative" "1")
14065            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14066               (const_string "ssemul")
14067               (const_string "sseadd"))
14068            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14069               (const_string "fmul")
14070               (const_string "fop"))))
14071    (set_attr "mode" "DF")])
14073 (define_insn "*fop_df_comm_sse"
14074   [(set (match_operand:DF 0 "register_operand" "=Y")
14075         (match_operator:DF 3 "binary_fp_operator"
14076                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14077                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14078   "TARGET_SSE2 && TARGET_SSE_MATH
14079    && COMMUTATIVE_ARITH_P (operands[3])
14080    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14081   "* return output_387_binary_op (insn, operands);"
14082   [(set (attr "type") 
14083         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14084            (const_string "ssemul")
14085            (const_string "sseadd")))
14086    (set_attr "mode" "DF")])
14088 (define_insn "*fop_df_comm_i387"
14089   [(set (match_operand:DF 0 "register_operand" "=f")
14090         (match_operator:DF 3 "binary_fp_operator"
14091                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14092                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14093   "TARGET_80387
14094    && COMMUTATIVE_ARITH_P (operands[3])
14095    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14096   "* return output_387_binary_op (insn, operands);"
14097   [(set (attr "type") 
14098         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14099            (const_string "fmul")
14100            (const_string "fop")))
14101    (set_attr "mode" "DF")])
14103 (define_insn "*fop_df_1_mixed"
14104   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14105         (match_operator:DF 3 "binary_fp_operator"
14106                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14107                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14108   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14109    && !COMMUTATIVE_ARITH_P (operands[3])
14110    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14111   "* return output_387_binary_op (insn, operands);"
14112   [(set (attr "type") 
14113         (cond [(and (eq_attr "alternative" "2")
14114                     (match_operand:SF 3 "mult_operator" ""))
14115                  (const_string "ssemul")
14116                (and (eq_attr "alternative" "2")
14117                     (match_operand:SF 3 "div_operator" ""))
14118                  (const_string "ssediv")
14119                (eq_attr "alternative" "2")
14120                  (const_string "sseadd")
14121                (match_operand:DF 3 "mult_operator" "") 
14122                  (const_string "fmul")
14123                (match_operand:DF 3 "div_operator" "") 
14124                  (const_string "fdiv")
14125               ]
14126               (const_string "fop")))
14127    (set_attr "mode" "DF")])
14129 (define_insn "*fop_df_1_sse"
14130   [(set (match_operand:DF 0 "register_operand" "=Y")
14131         (match_operator:DF 3 "binary_fp_operator"
14132                         [(match_operand:DF 1 "register_operand" "0")
14133                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14134   "TARGET_SSE2 && TARGET_SSE_MATH
14135    && !COMMUTATIVE_ARITH_P (operands[3])"
14136   "* return output_387_binary_op (insn, operands);"
14137   [(set_attr "mode" "DF")
14138    (set (attr "type") 
14139         (cond [(match_operand:SF 3 "mult_operator" "")
14140                  (const_string "ssemul")
14141                (match_operand:SF 3 "div_operator" "")
14142                  (const_string "ssediv")
14143               ]
14144               (const_string "sseadd")))])
14146 ;; This pattern is not fully shadowed by the pattern above.
14147 (define_insn "*fop_df_1_i387"
14148   [(set (match_operand:DF 0 "register_operand" "=f,f")
14149         (match_operator:DF 3 "binary_fp_operator"
14150                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14151                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14152   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14153    && !COMMUTATIVE_ARITH_P (operands[3])
14154    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14155   "* return output_387_binary_op (insn, operands);"
14156   [(set (attr "type") 
14157         (cond [(match_operand:DF 3 "mult_operator" "") 
14158                  (const_string "fmul")
14159                (match_operand:DF 3 "div_operator" "")
14160                  (const_string "fdiv")
14161               ]
14162               (const_string "fop")))
14163    (set_attr "mode" "DF")])
14165 ;; ??? Add SSE splitters for these!
14166 (define_insn "*fop_df_2<mode>_i387"
14167   [(set (match_operand:DF 0 "register_operand" "=f,f")
14168         (match_operator:DF 3 "binary_fp_operator"
14169            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14170             (match_operand:DF 2 "register_operand" "0,0")]))]
14171   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14172    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14173   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14174   [(set (attr "type") 
14175         (cond [(match_operand:DF 3 "mult_operator" "") 
14176                  (const_string "fmul")
14177                (match_operand:DF 3 "div_operator" "") 
14178                  (const_string "fdiv")
14179               ]
14180               (const_string "fop")))
14181    (set_attr "fp_int_src" "true")
14182    (set_attr "mode" "<MODE>")])
14184 (define_insn "*fop_df_3<mode>_i387"
14185   [(set (match_operand:DF 0 "register_operand" "=f,f")
14186         (match_operator:DF 3 "binary_fp_operator"
14187            [(match_operand:DF 1 "register_operand" "0,0")
14188             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14189   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14190    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14191   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14192   [(set (attr "type") 
14193         (cond [(match_operand:DF 3 "mult_operator" "") 
14194                  (const_string "fmul")
14195                (match_operand:DF 3 "div_operator" "") 
14196                  (const_string "fdiv")
14197               ]
14198               (const_string "fop")))
14199    (set_attr "fp_int_src" "true")
14200    (set_attr "mode" "<MODE>")])
14202 (define_insn "*fop_df_4_i387"
14203   [(set (match_operand:DF 0 "register_operand" "=f,f")
14204         (match_operator:DF 3 "binary_fp_operator"
14205            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14206             (match_operand:DF 2 "register_operand" "0,f")]))]
14207   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14208    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14209   "* return output_387_binary_op (insn, operands);"
14210   [(set (attr "type") 
14211         (cond [(match_operand:DF 3 "mult_operator" "") 
14212                  (const_string "fmul")
14213                (match_operand:DF 3 "div_operator" "") 
14214                  (const_string "fdiv")
14215               ]
14216               (const_string "fop")))
14217    (set_attr "mode" "SF")])
14219 (define_insn "*fop_df_5_i387"
14220   [(set (match_operand:DF 0 "register_operand" "=f,f")
14221         (match_operator:DF 3 "binary_fp_operator"
14222           [(match_operand:DF 1 "register_operand" "0,f")
14223            (float_extend:DF
14224             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14225   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14226   "* return output_387_binary_op (insn, operands);"
14227   [(set (attr "type") 
14228         (cond [(match_operand:DF 3 "mult_operator" "") 
14229                  (const_string "fmul")
14230                (match_operand:DF 3 "div_operator" "") 
14231                  (const_string "fdiv")
14232               ]
14233               (const_string "fop")))
14234    (set_attr "mode" "SF")])
14236 (define_insn "*fop_df_6_i387"
14237   [(set (match_operand:DF 0 "register_operand" "=f,f")
14238         (match_operator:DF 3 "binary_fp_operator"
14239           [(float_extend:DF
14240             (match_operand:SF 1 "register_operand" "0,f"))
14241            (float_extend:DF
14242             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14243   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14244   "* return output_387_binary_op (insn, operands);"
14245   [(set (attr "type") 
14246         (cond [(match_operand:DF 3 "mult_operator" "") 
14247                  (const_string "fmul")
14248                (match_operand:DF 3 "div_operator" "") 
14249                  (const_string "fdiv")
14250               ]
14251               (const_string "fop")))
14252    (set_attr "mode" "SF")])
14254 (define_insn "*fop_xf_comm_i387"
14255   [(set (match_operand:XF 0 "register_operand" "=f")
14256         (match_operator:XF 3 "binary_fp_operator"
14257                         [(match_operand:XF 1 "register_operand" "%0")
14258                          (match_operand:XF 2 "register_operand" "f")]))]
14259   "TARGET_80387
14260    && COMMUTATIVE_ARITH_P (operands[3])"
14261   "* return output_387_binary_op (insn, operands);"
14262   [(set (attr "type") 
14263         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14264            (const_string "fmul")
14265            (const_string "fop")))
14266    (set_attr "mode" "XF")])
14268 (define_insn "*fop_xf_1_i387"
14269   [(set (match_operand:XF 0 "register_operand" "=f,f")
14270         (match_operator:XF 3 "binary_fp_operator"
14271                         [(match_operand:XF 1 "register_operand" "0,f")
14272                          (match_operand:XF 2 "register_operand" "f,0")]))]
14273   "TARGET_80387
14274    && !COMMUTATIVE_ARITH_P (operands[3])"
14275   "* return output_387_binary_op (insn, operands);"
14276   [(set (attr "type") 
14277         (cond [(match_operand:XF 3 "mult_operator" "") 
14278                  (const_string "fmul")
14279                (match_operand:XF 3 "div_operator" "") 
14280                  (const_string "fdiv")
14281               ]
14282               (const_string "fop")))
14283    (set_attr "mode" "XF")])
14285 (define_insn "*fop_xf_2<mode>_i387"
14286   [(set (match_operand:XF 0 "register_operand" "=f,f")
14287         (match_operator:XF 3 "binary_fp_operator"
14288            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14289             (match_operand:XF 2 "register_operand" "0,0")]))]
14290   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14291   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14292   [(set (attr "type") 
14293         (cond [(match_operand:XF 3 "mult_operator" "") 
14294                  (const_string "fmul")
14295                (match_operand:XF 3 "div_operator" "") 
14296                  (const_string "fdiv")
14297               ]
14298               (const_string "fop")))
14299    (set_attr "fp_int_src" "true")
14300    (set_attr "mode" "<MODE>")])
14302 (define_insn "*fop_xf_3<mode>_i387"
14303   [(set (match_operand:XF 0 "register_operand" "=f,f")
14304         (match_operator:XF 3 "binary_fp_operator"
14305           [(match_operand:XF 1 "register_operand" "0,0")
14306            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14307   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14308   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14309   [(set (attr "type") 
14310         (cond [(match_operand:XF 3 "mult_operator" "") 
14311                  (const_string "fmul")
14312                (match_operand:XF 3 "div_operator" "") 
14313                  (const_string "fdiv")
14314               ]
14315               (const_string "fop")))
14316    (set_attr "fp_int_src" "true")
14317    (set_attr "mode" "<MODE>")])
14319 (define_insn "*fop_xf_4_i387"
14320   [(set (match_operand:XF 0 "register_operand" "=f,f")
14321         (match_operator:XF 3 "binary_fp_operator"
14322            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14323             (match_operand:XF 2 "register_operand" "0,f")]))]
14324   "TARGET_80387"
14325   "* return output_387_binary_op (insn, operands);"
14326   [(set (attr "type") 
14327         (cond [(match_operand:XF 3 "mult_operator" "") 
14328                  (const_string "fmul")
14329                (match_operand:XF 3 "div_operator" "") 
14330                  (const_string "fdiv")
14331               ]
14332               (const_string "fop")))
14333    (set_attr "mode" "SF")])
14335 (define_insn "*fop_xf_5_i387"
14336   [(set (match_operand:XF 0 "register_operand" "=f,f")
14337         (match_operator:XF 3 "binary_fp_operator"
14338           [(match_operand:XF 1 "register_operand" "0,f")
14339            (float_extend:XF
14340             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14341   "TARGET_80387"
14342   "* return output_387_binary_op (insn, operands);"
14343   [(set (attr "type") 
14344         (cond [(match_operand:XF 3 "mult_operator" "") 
14345                  (const_string "fmul")
14346                (match_operand:XF 3 "div_operator" "") 
14347                  (const_string "fdiv")
14348               ]
14349               (const_string "fop")))
14350    (set_attr "mode" "SF")])
14352 (define_insn "*fop_xf_6_i387"
14353   [(set (match_operand:XF 0 "register_operand" "=f,f")
14354         (match_operator:XF 3 "binary_fp_operator"
14355           [(float_extend:XF
14356             (match_operand 1 "register_operand" "0,f"))
14357            (float_extend:XF
14358             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14359   "TARGET_80387"
14360   "* return output_387_binary_op (insn, operands);"
14361   [(set (attr "type") 
14362         (cond [(match_operand:XF 3 "mult_operator" "") 
14363                  (const_string "fmul")
14364                (match_operand:XF 3 "div_operator" "") 
14365                  (const_string "fdiv")
14366               ]
14367               (const_string "fop")))
14368    (set_attr "mode" "SF")])
14370 (define_split
14371   [(set (match_operand 0 "register_operand" "")
14372         (match_operator 3 "binary_fp_operator"
14373            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14374             (match_operand 2 "register_operand" "")]))]
14375   "TARGET_80387 && reload_completed
14376    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14377   [(const_int 0)]
14379   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14380   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14381   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14382                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14383                                           GET_MODE (operands[3]),
14384                                           operands[4],
14385                                           operands[2])));
14386   ix86_free_from_memory (GET_MODE (operands[1]));
14387   DONE;
14390 (define_split
14391   [(set (match_operand 0 "register_operand" "")
14392         (match_operator 3 "binary_fp_operator"
14393            [(match_operand 1 "register_operand" "")
14394             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14395   "TARGET_80387 && reload_completed
14396    && FLOAT_MODE_P (GET_MODE (operands[0]))"
14397   [(const_int 0)]
14399   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14400   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14401   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14402                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
14403                                           GET_MODE (operands[3]),
14404                                           operands[1],
14405                                           operands[4])));
14406   ix86_free_from_memory (GET_MODE (operands[2]));
14407   DONE;
14410 ;; FPU special functions.
14412 (define_expand "sqrtsf2"
14413   [(set (match_operand:SF 0 "register_operand" "")
14414         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14415   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14417   if (!TARGET_SSE_MATH)
14418     operands[1] = force_reg (SFmode, operands[1]);
14421 (define_insn "*sqrtsf2_mixed"
14422   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14423         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14424   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14425   "@
14426    fsqrt
14427    sqrtss\t{%1, %0|%0, %1}"
14428   [(set_attr "type" "fpspc,sse")
14429    (set_attr "mode" "SF,SF")
14430    (set_attr "athlon_decode" "direct,*")])
14432 (define_insn "*sqrtsf2_sse"
14433   [(set (match_operand:SF 0 "register_operand" "=x")
14434         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14435   "TARGET_SSE_MATH"
14436   "sqrtss\t{%1, %0|%0, %1}"
14437   [(set_attr "type" "sse")
14438    (set_attr "mode" "SF")
14439    (set_attr "athlon_decode" "*")])
14441 (define_insn "*sqrtsf2_i387"
14442   [(set (match_operand:SF 0 "register_operand" "=f")
14443         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14444   "TARGET_USE_FANCY_MATH_387"
14445   "fsqrt"
14446   [(set_attr "type" "fpspc")
14447    (set_attr "mode" "SF")
14448    (set_attr "athlon_decode" "direct")])
14450 (define_expand "sqrtdf2"
14451   [(set (match_operand:DF 0 "register_operand" "")
14452         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14453   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14455   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14456     operands[1] = force_reg (DFmode, operands[1]);
14459 (define_insn "*sqrtdf2_mixed"
14460   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14461         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14462   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14463   "@
14464    fsqrt
14465    sqrtsd\t{%1, %0|%0, %1}"
14466   [(set_attr "type" "fpspc,sse")
14467    (set_attr "mode" "DF,DF")
14468    (set_attr "athlon_decode" "direct,*")])
14470 (define_insn "*sqrtdf2_sse"
14471   [(set (match_operand:DF 0 "register_operand" "=Y")
14472         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14473   "TARGET_SSE2 && TARGET_SSE_MATH"
14474   "sqrtsd\t{%1, %0|%0, %1}"
14475   [(set_attr "type" "sse")
14476    (set_attr "mode" "DF")
14477    (set_attr "athlon_decode" "*")])
14479 (define_insn "*sqrtdf2_i387"
14480   [(set (match_operand:DF 0 "register_operand" "=f")
14481         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14482   "TARGET_USE_FANCY_MATH_387"
14483   "fsqrt"
14484   [(set_attr "type" "fpspc")
14485    (set_attr "mode" "DF")
14486    (set_attr "athlon_decode" "direct")])
14488 (define_insn "*sqrtextendsfdf2_i387"
14489   [(set (match_operand:DF 0 "register_operand" "=f")
14490         (sqrt:DF (float_extend:DF
14491                   (match_operand:SF 1 "register_operand" "0"))))]
14492   "TARGET_USE_FANCY_MATH_387
14493    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14494   "fsqrt"
14495   [(set_attr "type" "fpspc")
14496    (set_attr "mode" "DF")
14497    (set_attr "athlon_decode" "direct")])
14499 (define_insn "sqrtxf2"
14500   [(set (match_operand:XF 0 "register_operand" "=f")
14501         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14502   "TARGET_USE_FANCY_MATH_387 
14503    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14504   "fsqrt"
14505   [(set_attr "type" "fpspc")
14506    (set_attr "mode" "XF")
14507    (set_attr "athlon_decode" "direct")])
14509 (define_insn "*sqrtextendsfxf2_i387"
14510   [(set (match_operand:XF 0 "register_operand" "=f")
14511         (sqrt:XF (float_extend:XF
14512                   (match_operand:SF 1 "register_operand" "0"))))]
14513   "TARGET_USE_FANCY_MATH_387"
14514   "fsqrt"
14515   [(set_attr "type" "fpspc")
14516    (set_attr "mode" "XF")
14517    (set_attr "athlon_decode" "direct")])
14519 (define_insn "*sqrtextenddfxf2_i387"
14520   [(set (match_operand:XF 0 "register_operand" "=f")
14521         (sqrt:XF (float_extend:XF
14522                   (match_operand:DF 1 "register_operand" "0"))))]
14523   "TARGET_USE_FANCY_MATH_387"
14524   "fsqrt"
14525   [(set_attr "type" "fpspc")
14526    (set_attr "mode" "XF")
14527    (set_attr "athlon_decode" "direct")])
14529 (define_insn "fpremxf4"
14530   [(set (match_operand:XF 0 "register_operand" "=f")
14531         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14532                     (match_operand:XF 3 "register_operand" "1")]
14533                    UNSPEC_FPREM_F))
14534    (set (match_operand:XF 1 "register_operand" "=u")
14535         (unspec:XF [(match_dup 2) (match_dup 3)]
14536                    UNSPEC_FPREM_U))
14537    (set (reg:CCFP FPSR_REG)
14538         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14539   "TARGET_USE_FANCY_MATH_387
14540    && flag_unsafe_math_optimizations"
14541   "fprem"
14542   [(set_attr "type" "fpspc")
14543    (set_attr "mode" "XF")])
14545 (define_expand "fmodsf3"
14546   [(use (match_operand:SF 0 "register_operand" ""))
14547    (use (match_operand:SF 1 "register_operand" ""))
14548    (use (match_operand:SF 2 "register_operand" ""))]
14549   "TARGET_USE_FANCY_MATH_387
14550    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14551    && flag_unsafe_math_optimizations"
14553   rtx label = gen_label_rtx ();
14555   rtx op1 = gen_reg_rtx (XFmode);
14556   rtx op2 = gen_reg_rtx (XFmode);
14558   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14559   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14561   emit_label (label);
14563   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14564   ix86_emit_fp_unordered_jump (label);
14566   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14567   DONE;
14570 (define_expand "fmoddf3"
14571   [(use (match_operand:DF 0 "register_operand" ""))
14572    (use (match_operand:DF 1 "register_operand" ""))
14573    (use (match_operand:DF 2 "register_operand" ""))]
14574   "TARGET_USE_FANCY_MATH_387
14575    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14576    && flag_unsafe_math_optimizations"
14578   rtx label = gen_label_rtx ();
14580   rtx op1 = gen_reg_rtx (XFmode);
14581   rtx op2 = gen_reg_rtx (XFmode);
14583   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14584   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14586   emit_label (label);
14588   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14589   ix86_emit_fp_unordered_jump (label);
14591   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14592   DONE;
14595 (define_expand "fmodxf3"
14596   [(use (match_operand:XF 0 "register_operand" ""))
14597    (use (match_operand:XF 1 "register_operand" ""))
14598    (use (match_operand:XF 2 "register_operand" ""))]
14599   "TARGET_USE_FANCY_MATH_387
14600    && flag_unsafe_math_optimizations"
14602   rtx label = gen_label_rtx ();
14604   emit_label (label);
14606   emit_insn (gen_fpremxf4 (operands[1], operands[2],
14607                            operands[1], operands[2]));
14608   ix86_emit_fp_unordered_jump (label);
14610   emit_move_insn (operands[0], operands[1]);
14611   DONE;
14614 (define_insn "fprem1xf4"
14615   [(set (match_operand:XF 0 "register_operand" "=f")
14616         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14617                     (match_operand:XF 3 "register_operand" "1")]
14618                    UNSPEC_FPREM1_F))
14619    (set (match_operand:XF 1 "register_operand" "=u")
14620         (unspec:XF [(match_dup 2) (match_dup 3)]
14621                    UNSPEC_FPREM1_U))
14622    (set (reg:CCFP FPSR_REG)
14623         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14624   "TARGET_USE_FANCY_MATH_387
14625    && flag_unsafe_math_optimizations"
14626   "fprem1"
14627   [(set_attr "type" "fpspc")
14628    (set_attr "mode" "XF")])
14630 (define_expand "dremsf3"
14631   [(use (match_operand:SF 0 "register_operand" ""))
14632    (use (match_operand:SF 1 "register_operand" ""))
14633    (use (match_operand:SF 2 "register_operand" ""))]
14634   "TARGET_USE_FANCY_MATH_387
14635    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14636    && flag_unsafe_math_optimizations"
14638   rtx label = gen_label_rtx ();
14640   rtx op1 = gen_reg_rtx (XFmode);
14641   rtx op2 = gen_reg_rtx (XFmode);
14643   emit_insn(gen_extendsfxf2 (op1, operands[1]));
14644   emit_insn(gen_extendsfxf2 (op2, operands[2]));
14646   emit_label (label);
14648   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14649   ix86_emit_fp_unordered_jump (label);
14651   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14652   DONE;
14655 (define_expand "dremdf3"
14656   [(use (match_operand:DF 0 "register_operand" ""))
14657    (use (match_operand:DF 1 "register_operand" ""))
14658    (use (match_operand:DF 2 "register_operand" ""))]
14659   "TARGET_USE_FANCY_MATH_387
14660    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14661    && flag_unsafe_math_optimizations"
14663   rtx label = gen_label_rtx ();
14665   rtx op1 = gen_reg_rtx (XFmode);
14666   rtx op2 = gen_reg_rtx (XFmode);
14668   emit_insn (gen_extenddfxf2 (op1, operands[1]));
14669   emit_insn (gen_extenddfxf2 (op2, operands[2]));
14671   emit_label (label);
14673   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14674   ix86_emit_fp_unordered_jump (label);
14676   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14677   DONE;
14680 (define_expand "dremxf3"
14681   [(use (match_operand:XF 0 "register_operand" ""))
14682    (use (match_operand:XF 1 "register_operand" ""))
14683    (use (match_operand:XF 2 "register_operand" ""))]
14684   "TARGET_USE_FANCY_MATH_387
14685    && flag_unsafe_math_optimizations"
14687   rtx label = gen_label_rtx ();
14689   emit_label (label);
14691   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14692                             operands[1], operands[2]));
14693   ix86_emit_fp_unordered_jump (label);
14695   emit_move_insn (operands[0], operands[1]);
14696   DONE;
14699 (define_insn "*sindf2"
14700   [(set (match_operand:DF 0 "register_operand" "=f")
14701         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14702   "TARGET_USE_FANCY_MATH_387
14703    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14704    && flag_unsafe_math_optimizations"
14705   "fsin"
14706   [(set_attr "type" "fpspc")
14707    (set_attr "mode" "DF")])
14709 (define_insn "*sinsf2"
14710   [(set (match_operand:SF 0 "register_operand" "=f")
14711         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14712   "TARGET_USE_FANCY_MATH_387
14713    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14714    && flag_unsafe_math_optimizations"
14715   "fsin"
14716   [(set_attr "type" "fpspc")
14717    (set_attr "mode" "SF")])
14719 (define_insn "*sinextendsfdf2"
14720   [(set (match_operand:DF 0 "register_operand" "=f")
14721         (unspec:DF [(float_extend:DF
14722                      (match_operand:SF 1 "register_operand" "0"))]
14723                    UNSPEC_SIN))]
14724   "TARGET_USE_FANCY_MATH_387
14725    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14726    && flag_unsafe_math_optimizations"
14727   "fsin"
14728   [(set_attr "type" "fpspc")
14729    (set_attr "mode" "DF")])
14731 (define_insn "*sinxf2"
14732   [(set (match_operand:XF 0 "register_operand" "=f")
14733         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14734   "TARGET_USE_FANCY_MATH_387
14735    && flag_unsafe_math_optimizations"
14736   "fsin"
14737   [(set_attr "type" "fpspc")
14738    (set_attr "mode" "XF")])
14740 (define_insn "*cosdf2"
14741   [(set (match_operand:DF 0 "register_operand" "=f")
14742         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14743   "TARGET_USE_FANCY_MATH_387
14744    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14745    && flag_unsafe_math_optimizations"
14746   "fcos"
14747   [(set_attr "type" "fpspc")
14748    (set_attr "mode" "DF")])
14750 (define_insn "*cossf2"
14751   [(set (match_operand:SF 0 "register_operand" "=f")
14752         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14753   "TARGET_USE_FANCY_MATH_387
14754    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14755    && flag_unsafe_math_optimizations"
14756   "fcos"
14757   [(set_attr "type" "fpspc")
14758    (set_attr "mode" "SF")])
14760 (define_insn "*cosextendsfdf2"
14761   [(set (match_operand:DF 0 "register_operand" "=f")
14762         (unspec:DF [(float_extend:DF
14763                      (match_operand:SF 1 "register_operand" "0"))]
14764                    UNSPEC_COS))]
14765   "TARGET_USE_FANCY_MATH_387
14766    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14767    && flag_unsafe_math_optimizations"
14768   "fcos"
14769   [(set_attr "type" "fpspc")
14770    (set_attr "mode" "DF")])
14772 (define_insn "*cosxf2"
14773   [(set (match_operand:XF 0 "register_operand" "=f")
14774         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14775   "TARGET_USE_FANCY_MATH_387
14776    && flag_unsafe_math_optimizations"
14777   "fcos"
14778   [(set_attr "type" "fpspc")
14779    (set_attr "mode" "XF")])
14781 ;; With sincos pattern defined, sin and cos builtin function will be
14782 ;; expanded to sincos pattern with one of its outputs left unused. 
14783 ;; Cse pass  will detected, if two sincos patterns can be combined,
14784 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14785 ;; depending on the unused output.
14787 (define_insn "sincosdf3"
14788   [(set (match_operand:DF 0 "register_operand" "=f")
14789         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14790                    UNSPEC_SINCOS_COS))
14791    (set (match_operand:DF 1 "register_operand" "=u")
14792         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14793   "TARGET_USE_FANCY_MATH_387
14794    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14795    && flag_unsafe_math_optimizations"
14796   "fsincos"
14797   [(set_attr "type" "fpspc")
14798    (set_attr "mode" "DF")])
14800 (define_split
14801   [(set (match_operand:DF 0 "register_operand" "")
14802         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14803                    UNSPEC_SINCOS_COS))
14804    (set (match_operand:DF 1 "register_operand" "")
14805         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14806   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14807    && !reload_completed && !reload_in_progress"
14808   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14809   "")
14811 (define_split
14812   [(set (match_operand:DF 0 "register_operand" "")
14813         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14814                    UNSPEC_SINCOS_COS))
14815    (set (match_operand:DF 1 "register_operand" "")
14816         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14817   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14818    && !reload_completed && !reload_in_progress"
14819   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14820   "")
14822 (define_insn "sincossf3"
14823   [(set (match_operand:SF 0 "register_operand" "=f")
14824         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14825                    UNSPEC_SINCOS_COS))
14826    (set (match_operand:SF 1 "register_operand" "=u")
14827         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14828   "TARGET_USE_FANCY_MATH_387
14829    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14830    && flag_unsafe_math_optimizations"
14831   "fsincos"
14832   [(set_attr "type" "fpspc")
14833    (set_attr "mode" "SF")])
14835 (define_split
14836   [(set (match_operand:SF 0 "register_operand" "")
14837         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14838                    UNSPEC_SINCOS_COS))
14839    (set (match_operand:SF 1 "register_operand" "")
14840         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14841   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14842    && !reload_completed && !reload_in_progress"
14843   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14844   "")
14846 (define_split
14847   [(set (match_operand:SF 0 "register_operand" "")
14848         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14849                    UNSPEC_SINCOS_COS))
14850    (set (match_operand:SF 1 "register_operand" "")
14851         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14852   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14853    && !reload_completed && !reload_in_progress"
14854   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14855   "")
14857 (define_insn "*sincosextendsfdf3"
14858   [(set (match_operand:DF 0 "register_operand" "=f")
14859         (unspec:DF [(float_extend:DF
14860                      (match_operand:SF 2 "register_operand" "0"))]
14861                    UNSPEC_SINCOS_COS))
14862    (set (match_operand:DF 1 "register_operand" "=u")
14863         (unspec:DF [(float_extend:DF
14864                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14865   "TARGET_USE_FANCY_MATH_387
14866    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14867    && flag_unsafe_math_optimizations"
14868   "fsincos"
14869   [(set_attr "type" "fpspc")
14870    (set_attr "mode" "DF")])
14872 (define_split
14873   [(set (match_operand:DF 0 "register_operand" "")
14874         (unspec:DF [(float_extend:DF
14875                      (match_operand:SF 2 "register_operand" ""))]
14876                    UNSPEC_SINCOS_COS))
14877    (set (match_operand:DF 1 "register_operand" "")
14878         (unspec:DF [(float_extend:DF
14879                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14880   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14881    && !reload_completed && !reload_in_progress"
14882   [(set (match_dup 1) (unspec:DF [(float_extend:DF
14883                                    (match_dup 2))] UNSPEC_SIN))]
14884   "")
14886 (define_split
14887   [(set (match_operand:DF 0 "register_operand" "")
14888         (unspec:DF [(float_extend:DF
14889                      (match_operand:SF 2 "register_operand" ""))]
14890                    UNSPEC_SINCOS_COS))
14891    (set (match_operand:DF 1 "register_operand" "")
14892         (unspec:DF [(float_extend:DF
14893                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
14894   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14895    && !reload_completed && !reload_in_progress"
14896   [(set (match_dup 0) (unspec:DF [(float_extend:DF
14897                                    (match_dup 2))] UNSPEC_COS))]
14898   "")
14900 (define_insn "sincosxf3"
14901   [(set (match_operand:XF 0 "register_operand" "=f")
14902         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14903                    UNSPEC_SINCOS_COS))
14904    (set (match_operand:XF 1 "register_operand" "=u")
14905         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14906   "TARGET_USE_FANCY_MATH_387
14907    && flag_unsafe_math_optimizations"
14908   "fsincos"
14909   [(set_attr "type" "fpspc")
14910    (set_attr "mode" "XF")])
14912 (define_split
14913   [(set (match_operand:XF 0 "register_operand" "")
14914         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14915                    UNSPEC_SINCOS_COS))
14916    (set (match_operand:XF 1 "register_operand" "")
14917         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14918   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14919    && !reload_completed && !reload_in_progress"
14920   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
14921   "")
14923 (define_split
14924   [(set (match_operand:XF 0 "register_operand" "")
14925         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
14926                    UNSPEC_SINCOS_COS))
14927    (set (match_operand:XF 1 "register_operand" "")
14928         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14929   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14930    && !reload_completed && !reload_in_progress"
14931   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
14932   "")
14934 (define_insn "*tandf3_1"
14935   [(set (match_operand:DF 0 "register_operand" "=f")
14936         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14937                    UNSPEC_TAN_ONE))
14938    (set (match_operand:DF 1 "register_operand" "=u")
14939         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
14940   "TARGET_USE_FANCY_MATH_387
14941    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14942    && flag_unsafe_math_optimizations"
14943   "fptan"
14944   [(set_attr "type" "fpspc")
14945    (set_attr "mode" "DF")])
14947 ;; optimize sequence: fptan
14948 ;;                    fstp    %st(0)
14949 ;;                    fld1
14950 ;; into fptan insn.
14952 (define_peephole2
14953   [(parallel[(set (match_operand:DF 0 "register_operand" "")
14954                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14955                              UNSPEC_TAN_ONE))
14956              (set (match_operand:DF 1 "register_operand" "")
14957                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
14958    (set (match_dup 0)
14959         (match_operand:DF 3 "immediate_operand" ""))]
14960   "standard_80387_constant_p (operands[3]) == 2"
14961   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
14962              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
14963   "")
14965 (define_expand "tandf2"
14966   [(parallel [(set (match_dup 2)
14967                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
14968                               UNSPEC_TAN_ONE))
14969               (set (match_operand:DF 0 "register_operand" "")
14970                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
14971   "TARGET_USE_FANCY_MATH_387
14972    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14973    && flag_unsafe_math_optimizations"
14975   operands[2] = gen_reg_rtx (DFmode);
14978 (define_insn "*tansf3_1"
14979   [(set (match_operand:SF 0 "register_operand" "=f")
14980         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14981                    UNSPEC_TAN_ONE))
14982    (set (match_operand:SF 1 "register_operand" "=u")
14983         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
14984   "TARGET_USE_FANCY_MATH_387
14985    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14986    && flag_unsafe_math_optimizations"
14987   "fptan"
14988   [(set_attr "type" "fpspc")
14989    (set_attr "mode" "SF")])
14991 ;; optimize sequence: fptan
14992 ;;                    fstp    %st(0)
14993 ;;                    fld1
14994 ;; into fptan insn.
14996 (define_peephole2
14997   [(parallel[(set (match_operand:SF 0 "register_operand" "")
14998                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14999                              UNSPEC_TAN_ONE))
15000              (set (match_operand:SF 1 "register_operand" "")
15001                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15002    (set (match_dup 0)
15003         (match_operand:SF 3 "immediate_operand" ""))]
15004   "standard_80387_constant_p (operands[3]) == 2"
15005   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15006              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15007   "")
15009 (define_expand "tansf2"
15010   [(parallel [(set (match_dup 2)
15011                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15012                               UNSPEC_TAN_ONE))
15013               (set (match_operand:SF 0 "register_operand" "")
15014                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15015   "TARGET_USE_FANCY_MATH_387
15016    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15017    && flag_unsafe_math_optimizations"
15019   operands[2] = gen_reg_rtx (SFmode);
15022 (define_insn "*tanxf3_1"
15023   [(set (match_operand:XF 0 "register_operand" "=f")
15024         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15025                    UNSPEC_TAN_ONE))
15026    (set (match_operand:XF 1 "register_operand" "=u")
15027         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15028   "TARGET_USE_FANCY_MATH_387
15029    && flag_unsafe_math_optimizations"
15030   "fptan"
15031   [(set_attr "type" "fpspc")
15032    (set_attr "mode" "XF")])
15034 ;; optimize sequence: fptan
15035 ;;                    fstp    %st(0)
15036 ;;                    fld1
15037 ;; into fptan insn.
15039 (define_peephole2
15040   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15041                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15042                              UNSPEC_TAN_ONE))
15043              (set (match_operand:XF 1 "register_operand" "")
15044                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15045    (set (match_dup 0)
15046         (match_operand:XF 3 "immediate_operand" ""))]
15047   "standard_80387_constant_p (operands[3]) == 2"
15048   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15049              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15050   "")
15052 (define_expand "tanxf2"
15053   [(parallel [(set (match_dup 2)
15054                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15055                               UNSPEC_TAN_ONE))
15056               (set (match_operand:XF 0 "register_operand" "")
15057                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15058   "TARGET_USE_FANCY_MATH_387
15059    && flag_unsafe_math_optimizations"
15061   operands[2] = gen_reg_rtx (XFmode);
15064 (define_insn "atan2df3_1"
15065   [(set (match_operand:DF 0 "register_operand" "=f")
15066         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15067                     (match_operand:DF 1 "register_operand" "u")]
15068                    UNSPEC_FPATAN))
15069    (clobber (match_scratch:DF 3 "=1"))]
15070   "TARGET_USE_FANCY_MATH_387
15071    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15072    && flag_unsafe_math_optimizations"
15073   "fpatan"
15074   [(set_attr "type" "fpspc")
15075    (set_attr "mode" "DF")])
15077 (define_expand "atan2df3"
15078   [(use (match_operand:DF 0 "register_operand" ""))
15079    (use (match_operand:DF 2 "register_operand" ""))
15080    (use (match_operand:DF 1 "register_operand" ""))]
15081   "TARGET_USE_FANCY_MATH_387
15082    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15083    && flag_unsafe_math_optimizations"
15085   rtx copy = gen_reg_rtx (DFmode);
15086   emit_move_insn (copy, operands[1]);
15087   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15088   DONE;
15091 (define_expand "atandf2"
15092   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15093                    (unspec:DF [(match_dup 2)
15094                                (match_operand:DF 1 "register_operand" "")]
15095                     UNSPEC_FPATAN))
15096               (clobber (match_scratch:DF 3 ""))])]
15097   "TARGET_USE_FANCY_MATH_387
15098    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15099    && flag_unsafe_math_optimizations"
15101   operands[2] = gen_reg_rtx (DFmode);
15102   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15105 (define_insn "atan2sf3_1"
15106   [(set (match_operand:SF 0 "register_operand" "=f")
15107         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15108                     (match_operand:SF 1 "register_operand" "u")]
15109                    UNSPEC_FPATAN))
15110    (clobber (match_scratch:SF 3 "=1"))]
15111   "TARGET_USE_FANCY_MATH_387
15112    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15113    && flag_unsafe_math_optimizations"
15114   "fpatan"
15115   [(set_attr "type" "fpspc")
15116    (set_attr "mode" "SF")])
15118 (define_expand "atan2sf3"
15119   [(use (match_operand:SF 0 "register_operand" ""))
15120    (use (match_operand:SF 2 "register_operand" ""))
15121    (use (match_operand:SF 1 "register_operand" ""))]
15122   "TARGET_USE_FANCY_MATH_387
15123    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15124    && flag_unsafe_math_optimizations"
15126   rtx copy = gen_reg_rtx (SFmode);
15127   emit_move_insn (copy, operands[1]);
15128   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15129   DONE;
15132 (define_expand "atansf2"
15133   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15134                    (unspec:SF [(match_dup 2)
15135                                (match_operand:SF 1 "register_operand" "")]
15136                     UNSPEC_FPATAN))
15137               (clobber (match_scratch:SF 3 ""))])]
15138   "TARGET_USE_FANCY_MATH_387
15139    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15140    && flag_unsafe_math_optimizations"
15142   operands[2] = gen_reg_rtx (SFmode);
15143   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15146 (define_insn "atan2xf3_1"
15147   [(set (match_operand:XF 0 "register_operand" "=f")
15148         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15149                     (match_operand:XF 1 "register_operand" "u")]
15150                    UNSPEC_FPATAN))
15151    (clobber (match_scratch:XF 3 "=1"))]
15152   "TARGET_USE_FANCY_MATH_387
15153    && flag_unsafe_math_optimizations"
15154   "fpatan"
15155   [(set_attr "type" "fpspc")
15156    (set_attr "mode" "XF")])
15158 (define_expand "atan2xf3"
15159   [(use (match_operand:XF 0 "register_operand" ""))
15160    (use (match_operand:XF 2 "register_operand" ""))
15161    (use (match_operand:XF 1 "register_operand" ""))]
15162   "TARGET_USE_FANCY_MATH_387
15163    && flag_unsafe_math_optimizations"
15165   rtx copy = gen_reg_rtx (XFmode);
15166   emit_move_insn (copy, operands[1]);
15167   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15168   DONE;
15171 (define_expand "atanxf2"
15172   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15173                    (unspec:XF [(match_dup 2)
15174                                (match_operand:XF 1 "register_operand" "")]
15175                     UNSPEC_FPATAN))
15176               (clobber (match_scratch:XF 3 ""))])]
15177   "TARGET_USE_FANCY_MATH_387
15178    && flag_unsafe_math_optimizations"
15180   operands[2] = gen_reg_rtx (XFmode);
15181   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15184 (define_expand "asindf2"
15185   [(set (match_dup 2)
15186         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15187    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15188    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15189    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15190    (parallel [(set (match_dup 7)
15191                    (unspec:XF [(match_dup 6) (match_dup 2)]
15192                               UNSPEC_FPATAN))
15193               (clobber (match_scratch:XF 8 ""))])
15194    (set (match_operand:DF 0 "register_operand" "")
15195         (float_truncate:DF (match_dup 7)))]
15196   "TARGET_USE_FANCY_MATH_387
15197    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15198    && flag_unsafe_math_optimizations"
15200   int i;
15202   for (i=2; i<8; i++)
15203     operands[i] = gen_reg_rtx (XFmode);
15205   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15208 (define_expand "asinsf2"
15209   [(set (match_dup 2)
15210         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15211    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15212    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15213    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15214    (parallel [(set (match_dup 7)
15215                    (unspec:XF [(match_dup 6) (match_dup 2)]
15216                               UNSPEC_FPATAN))
15217               (clobber (match_scratch:XF 8 ""))])
15218    (set (match_operand:SF 0 "register_operand" "")
15219         (float_truncate:SF (match_dup 7)))]
15220   "TARGET_USE_FANCY_MATH_387
15221    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15222    && flag_unsafe_math_optimizations"
15224   int i;
15226   for (i=2; i<8; i++)
15227     operands[i] = gen_reg_rtx (XFmode);
15229   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15232 (define_expand "asinxf2"
15233   [(set (match_dup 2)
15234         (mult:XF (match_operand:XF 1 "register_operand" "")
15235                  (match_dup 1)))
15236    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15237    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15238    (parallel [(set (match_operand:XF 0 "register_operand" "")
15239                    (unspec:XF [(match_dup 5) (match_dup 1)]
15240                               UNSPEC_FPATAN))
15241               (clobber (match_scratch:XF 6 ""))])]
15242   "TARGET_USE_FANCY_MATH_387
15243    && flag_unsafe_math_optimizations"
15245   int i;
15247   for (i=2; i<6; i++)
15248     operands[i] = gen_reg_rtx (XFmode);
15250   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15253 (define_expand "acosdf2"
15254   [(set (match_dup 2)
15255         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15256    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15257    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15258    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15259    (parallel [(set (match_dup 7)
15260                    (unspec:XF [(match_dup 2) (match_dup 6)]
15261                               UNSPEC_FPATAN))
15262               (clobber (match_scratch:XF 8 ""))])
15263    (set (match_operand:DF 0 "register_operand" "")
15264         (float_truncate:DF (match_dup 7)))]
15265   "TARGET_USE_FANCY_MATH_387
15266    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15267    && flag_unsafe_math_optimizations"
15269   int i;
15271   for (i=2; i<8; i++)
15272     operands[i] = gen_reg_rtx (XFmode);
15274   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15277 (define_expand "acossf2"
15278   [(set (match_dup 2)
15279         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15280    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15281    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15282    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15283    (parallel [(set (match_dup 7)
15284                    (unspec:XF [(match_dup 2) (match_dup 6)]
15285                               UNSPEC_FPATAN))
15286               (clobber (match_scratch:XF 8 ""))])
15287    (set (match_operand:SF 0 "register_operand" "")
15288         (float_truncate:SF (match_dup 7)))]
15289   "TARGET_USE_FANCY_MATH_387
15290    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15291    && flag_unsafe_math_optimizations"
15293   int i;
15295   for (i=2; i<8; i++)
15296     operands[i] = gen_reg_rtx (XFmode);
15298   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15301 (define_expand "acosxf2"
15302   [(set (match_dup 2)
15303         (mult:XF (match_operand:XF 1 "register_operand" "")
15304                  (match_dup 1)))
15305    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15306    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15307    (parallel [(set (match_operand:XF 0 "register_operand" "")
15308                    (unspec:XF [(match_dup 1) (match_dup 5)]
15309                               UNSPEC_FPATAN))
15310               (clobber (match_scratch:XF 6 ""))])]
15311   "TARGET_USE_FANCY_MATH_387
15312    && flag_unsafe_math_optimizations"
15314   int i;
15316   for (i=2; i<6; i++)
15317     operands[i] = gen_reg_rtx (XFmode);
15319   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15322 (define_insn "fyl2x_xf3"
15323   [(set (match_operand:XF 0 "register_operand" "=f")
15324         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15325                     (match_operand:XF 1 "register_operand" "u")]
15326                    UNSPEC_FYL2X))
15327    (clobber (match_scratch:XF 3 "=1"))]
15328   "TARGET_USE_FANCY_MATH_387
15329    && flag_unsafe_math_optimizations"
15330   "fyl2x"
15331   [(set_attr "type" "fpspc")
15332    (set_attr "mode" "XF")])
15334 (define_expand "logsf2"
15335   [(set (match_dup 2)
15336         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15337    (parallel [(set (match_dup 4)
15338                    (unspec:XF [(match_dup 2)
15339                                (match_dup 3)] UNSPEC_FYL2X))
15340               (clobber (match_scratch:XF 5 ""))])
15341    (set (match_operand:SF 0 "register_operand" "")
15342         (float_truncate:SF (match_dup 4)))]
15343   "TARGET_USE_FANCY_MATH_387
15344    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15345    && flag_unsafe_math_optimizations"
15347   rtx temp;
15349   operands[2] = gen_reg_rtx (XFmode);
15350   operands[3] = gen_reg_rtx (XFmode);
15351   operands[4] = gen_reg_rtx (XFmode);
15353   temp = standard_80387_constant_rtx (4); /* fldln2 */
15354   emit_move_insn (operands[3], temp);
15357 (define_expand "logdf2"
15358   [(set (match_dup 2)
15359         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15360    (parallel [(set (match_dup 4)
15361                    (unspec:XF [(match_dup 2)
15362                                (match_dup 3)] UNSPEC_FYL2X))
15363               (clobber (match_scratch:XF 5 ""))])
15364    (set (match_operand:DF 0 "register_operand" "")
15365         (float_truncate:DF (match_dup 4)))]
15366   "TARGET_USE_FANCY_MATH_387
15367    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15368    && flag_unsafe_math_optimizations"
15370   rtx temp;
15372   operands[2] = gen_reg_rtx (XFmode);
15373   operands[3] = gen_reg_rtx (XFmode);
15374   operands[4] = gen_reg_rtx (XFmode);
15376   temp = standard_80387_constant_rtx (4); /* fldln2 */
15377   emit_move_insn (operands[3], temp);
15380 (define_expand "logxf2"
15381   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15382                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15383                                (match_dup 2)] UNSPEC_FYL2X))
15384               (clobber (match_scratch:XF 3 ""))])]
15385   "TARGET_USE_FANCY_MATH_387
15386    && flag_unsafe_math_optimizations"
15388   rtx temp;
15390   operands[2] = gen_reg_rtx (XFmode);
15391   temp = standard_80387_constant_rtx (4); /* fldln2 */
15392   emit_move_insn (operands[2], temp);
15395 (define_expand "log10sf2"
15396   [(set (match_dup 2)
15397         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15398    (parallel [(set (match_dup 4)
15399                    (unspec:XF [(match_dup 2)
15400                                (match_dup 3)] UNSPEC_FYL2X))
15401               (clobber (match_scratch:XF 5 ""))])
15402    (set (match_operand:SF 0 "register_operand" "")
15403         (float_truncate:SF (match_dup 4)))]
15404   "TARGET_USE_FANCY_MATH_387
15405    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15406    && flag_unsafe_math_optimizations"
15408   rtx temp;
15410   operands[2] = gen_reg_rtx (XFmode);
15411   operands[3] = gen_reg_rtx (XFmode);
15412   operands[4] = gen_reg_rtx (XFmode);
15414   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15415   emit_move_insn (operands[3], temp);
15418 (define_expand "log10df2"
15419   [(set (match_dup 2)
15420         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15421    (parallel [(set (match_dup 4)
15422                    (unspec:XF [(match_dup 2)
15423                                (match_dup 3)] UNSPEC_FYL2X))
15424               (clobber (match_scratch:XF 5 ""))])
15425    (set (match_operand:DF 0 "register_operand" "")
15426         (float_truncate:DF (match_dup 4)))]
15427   "TARGET_USE_FANCY_MATH_387
15428    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15429    && flag_unsafe_math_optimizations"
15431   rtx temp;
15433   operands[2] = gen_reg_rtx (XFmode);
15434   operands[3] = gen_reg_rtx (XFmode);
15435   operands[4] = gen_reg_rtx (XFmode);
15437   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15438   emit_move_insn (operands[3], temp);
15441 (define_expand "log10xf2"
15442   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15443                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15444                                (match_dup 2)] UNSPEC_FYL2X))
15445               (clobber (match_scratch:XF 3 ""))])]
15446   "TARGET_USE_FANCY_MATH_387
15447    && flag_unsafe_math_optimizations"
15449   rtx temp;
15451   operands[2] = gen_reg_rtx (XFmode);
15452   temp = standard_80387_constant_rtx (3); /* fldlg2 */
15453   emit_move_insn (operands[2], temp);
15456 (define_expand "log2sf2"
15457   [(set (match_dup 2)
15458         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15459    (parallel [(set (match_dup 4)
15460                    (unspec:XF [(match_dup 2)
15461                                (match_dup 3)] UNSPEC_FYL2X))
15462               (clobber (match_scratch:XF 5 ""))])
15463    (set (match_operand:SF 0 "register_operand" "")
15464         (float_truncate:SF (match_dup 4)))]
15465   "TARGET_USE_FANCY_MATH_387
15466    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15467    && flag_unsafe_math_optimizations"
15469   operands[2] = gen_reg_rtx (XFmode);
15470   operands[3] = gen_reg_rtx (XFmode);
15471   operands[4] = gen_reg_rtx (XFmode);
15473   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15476 (define_expand "log2df2"
15477   [(set (match_dup 2)
15478         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15479    (parallel [(set (match_dup 4)
15480                    (unspec:XF [(match_dup 2)
15481                                (match_dup 3)] UNSPEC_FYL2X))
15482               (clobber (match_scratch:XF 5 ""))])
15483    (set (match_operand:DF 0 "register_operand" "")
15484         (float_truncate:DF (match_dup 4)))]
15485   "TARGET_USE_FANCY_MATH_387
15486    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15487    && flag_unsafe_math_optimizations"
15489   operands[2] = gen_reg_rtx (XFmode);
15490   operands[3] = gen_reg_rtx (XFmode);
15491   operands[4] = gen_reg_rtx (XFmode);
15493   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15496 (define_expand "log2xf2"
15497   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15498                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15499                                (match_dup 2)] UNSPEC_FYL2X))
15500               (clobber (match_scratch:XF 3 ""))])]
15501   "TARGET_USE_FANCY_MATH_387
15502    && flag_unsafe_math_optimizations"
15504   operands[2] = gen_reg_rtx (XFmode);
15505   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15508 (define_insn "fyl2xp1_xf3"
15509   [(set (match_operand:XF 0 "register_operand" "=f")
15510         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15511                     (match_operand:XF 1 "register_operand" "u")]
15512                    UNSPEC_FYL2XP1))
15513    (clobber (match_scratch:XF 3 "=1"))]
15514   "TARGET_USE_FANCY_MATH_387
15515    && flag_unsafe_math_optimizations"
15516   "fyl2xp1"
15517   [(set_attr "type" "fpspc")
15518    (set_attr "mode" "XF")])
15520 (define_expand "log1psf2"
15521   [(use (match_operand:SF 0 "register_operand" ""))
15522    (use (match_operand:SF 1 "register_operand" ""))]
15523   "TARGET_USE_FANCY_MATH_387
15524    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15525    && flag_unsafe_math_optimizations"
15527   rtx op0 = gen_reg_rtx (XFmode);
15528   rtx op1 = gen_reg_rtx (XFmode);
15530   emit_insn (gen_extendsfxf2 (op1, operands[1]));
15531   ix86_emit_i387_log1p (op0, op1);
15532   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15533   DONE;
15536 (define_expand "log1pdf2"
15537   [(use (match_operand:DF 0 "register_operand" ""))
15538    (use (match_operand:DF 1 "register_operand" ""))]
15539   "TARGET_USE_FANCY_MATH_387
15540    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15541    && flag_unsafe_math_optimizations"
15543   rtx op0 = gen_reg_rtx (XFmode);
15544   rtx op1 = gen_reg_rtx (XFmode);
15546   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15547   ix86_emit_i387_log1p (op0, op1);
15548   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15549   DONE;
15552 (define_expand "log1pxf2"
15553   [(use (match_operand:XF 0 "register_operand" ""))
15554    (use (match_operand:XF 1 "register_operand" ""))]
15555   "TARGET_USE_FANCY_MATH_387
15556    && flag_unsafe_math_optimizations"
15558   ix86_emit_i387_log1p (operands[0], operands[1]);
15559   DONE;
15562 (define_insn "*fxtractxf3"
15563   [(set (match_operand:XF 0 "register_operand" "=f")
15564         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15565                    UNSPEC_XTRACT_FRACT))
15566    (set (match_operand:XF 1 "register_operand" "=u")
15567         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15568   "TARGET_USE_FANCY_MATH_387
15569    && flag_unsafe_math_optimizations"
15570   "fxtract"
15571   [(set_attr "type" "fpspc")
15572    (set_attr "mode" "XF")])
15574 (define_expand "logbsf2"
15575   [(set (match_dup 2)
15576         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15577    (parallel [(set (match_dup 3)
15578                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15579               (set (match_dup 4)
15580                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15581    (set (match_operand:SF 0 "register_operand" "")
15582         (float_truncate:SF (match_dup 4)))]
15583   "TARGET_USE_FANCY_MATH_387
15584    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15585    && flag_unsafe_math_optimizations"
15587   operands[2] = gen_reg_rtx (XFmode);
15588   operands[3] = gen_reg_rtx (XFmode);
15589   operands[4] = gen_reg_rtx (XFmode);
15592 (define_expand "logbdf2"
15593   [(set (match_dup 2)
15594         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15595    (parallel [(set (match_dup 3)
15596                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15597               (set (match_dup 4)
15598                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15599    (set (match_operand:DF 0 "register_operand" "")
15600         (float_truncate:DF (match_dup 4)))]
15601   "TARGET_USE_FANCY_MATH_387
15602    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15603    && flag_unsafe_math_optimizations"
15605   operands[2] = gen_reg_rtx (XFmode);
15606   operands[3] = gen_reg_rtx (XFmode);
15607   operands[4] = gen_reg_rtx (XFmode);
15610 (define_expand "logbxf2"
15611   [(parallel [(set (match_dup 2)
15612                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15613                               UNSPEC_XTRACT_FRACT))
15614               (set (match_operand:XF 0 "register_operand" "")
15615                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15616   "TARGET_USE_FANCY_MATH_387
15617    && flag_unsafe_math_optimizations"
15619   operands[2] = gen_reg_rtx (XFmode);
15622 (define_expand "ilogbsi2"
15623   [(parallel [(set (match_dup 2)
15624                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15625                               UNSPEC_XTRACT_FRACT))
15626               (set (match_operand:XF 3 "register_operand" "")
15627                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15628    (parallel [(set (match_operand:SI 0 "register_operand" "")
15629                    (fix:SI (match_dup 3)))
15630               (clobber (reg:CC FLAGS_REG))])]
15631   "TARGET_USE_FANCY_MATH_387
15632    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15633    && flag_unsafe_math_optimizations"
15635   operands[2] = gen_reg_rtx (XFmode);
15636   operands[3] = gen_reg_rtx (XFmode);
15639 (define_insn "*f2xm1xf2"
15640   [(set (match_operand:XF 0 "register_operand" "=f")
15641         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15642          UNSPEC_F2XM1))]
15643   "TARGET_USE_FANCY_MATH_387
15644    && flag_unsafe_math_optimizations"
15645   "f2xm1"
15646   [(set_attr "type" "fpspc")
15647    (set_attr "mode" "XF")])
15649 (define_insn "*fscalexf4"
15650   [(set (match_operand:XF 0 "register_operand" "=f")
15651         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15652                     (match_operand:XF 3 "register_operand" "1")]
15653                    UNSPEC_FSCALE_FRACT))
15654    (set (match_operand:XF 1 "register_operand" "=u")
15655         (unspec:XF [(match_dup 2) (match_dup 3)]
15656                    UNSPEC_FSCALE_EXP))]
15657   "TARGET_USE_FANCY_MATH_387
15658    && flag_unsafe_math_optimizations"
15659   "fscale"
15660   [(set_attr "type" "fpspc")
15661    (set_attr "mode" "XF")])
15663 (define_expand "expsf2"
15664   [(set (match_dup 2)
15665         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15666    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15667    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15668    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15669    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15670    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15671    (parallel [(set (match_dup 10)
15672                    (unspec:XF [(match_dup 9) (match_dup 5)]
15673                               UNSPEC_FSCALE_FRACT))
15674               (set (match_dup 11)
15675                    (unspec:XF [(match_dup 9) (match_dup 5)]
15676                               UNSPEC_FSCALE_EXP))])
15677    (set (match_operand:SF 0 "register_operand" "")
15678         (float_truncate:SF (match_dup 10)))]
15679   "TARGET_USE_FANCY_MATH_387
15680    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15681    && flag_unsafe_math_optimizations"
15683   rtx temp;
15684   int i;
15686   for (i=2; i<12; i++)
15687     operands[i] = gen_reg_rtx (XFmode);
15688   temp = standard_80387_constant_rtx (5); /* fldl2e */
15689   emit_move_insn (operands[3], temp);
15690   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15693 (define_expand "expdf2"
15694   [(set (match_dup 2)
15695         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15696    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15697    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15698    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15699    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15700    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15701    (parallel [(set (match_dup 10)
15702                    (unspec:XF [(match_dup 9) (match_dup 5)]
15703                               UNSPEC_FSCALE_FRACT))
15704               (set (match_dup 11)
15705                    (unspec:XF [(match_dup 9) (match_dup 5)]
15706                               UNSPEC_FSCALE_EXP))])
15707    (set (match_operand:DF 0 "register_operand" "")
15708         (float_truncate:DF (match_dup 10)))]
15709   "TARGET_USE_FANCY_MATH_387
15710    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15711    && flag_unsafe_math_optimizations"
15713   rtx temp;
15714   int i;
15716   for (i=2; i<12; i++)
15717     operands[i] = gen_reg_rtx (XFmode);
15718   temp = standard_80387_constant_rtx (5); /* fldl2e */
15719   emit_move_insn (operands[3], temp);
15720   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15723 (define_expand "expxf2"
15724   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15725                                (match_dup 2)))
15726    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15727    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15728    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15729    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15730    (parallel [(set (match_operand:XF 0 "register_operand" "")
15731                    (unspec:XF [(match_dup 8) (match_dup 4)]
15732                               UNSPEC_FSCALE_FRACT))
15733               (set (match_dup 9)
15734                    (unspec:XF [(match_dup 8) (match_dup 4)]
15735                               UNSPEC_FSCALE_EXP))])]
15736   "TARGET_USE_FANCY_MATH_387
15737    && flag_unsafe_math_optimizations"
15739   rtx temp;
15740   int i;
15742   for (i=2; i<10; i++)
15743     operands[i] = gen_reg_rtx (XFmode);
15744   temp = standard_80387_constant_rtx (5); /* fldl2e */
15745   emit_move_insn (operands[2], temp);
15746   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15749 (define_expand "exp10sf2"
15750   [(set (match_dup 2)
15751         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15752    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15753    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15754    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15755    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15756    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15757    (parallel [(set (match_dup 10)
15758                    (unspec:XF [(match_dup 9) (match_dup 5)]
15759                               UNSPEC_FSCALE_FRACT))
15760               (set (match_dup 11)
15761                    (unspec:XF [(match_dup 9) (match_dup 5)]
15762                               UNSPEC_FSCALE_EXP))])
15763    (set (match_operand:SF 0 "register_operand" "")
15764         (float_truncate:SF (match_dup 10)))]
15765   "TARGET_USE_FANCY_MATH_387
15766    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15767    && flag_unsafe_math_optimizations"
15769   rtx temp;
15770   int i;
15772   for (i=2; i<12; i++)
15773     operands[i] = gen_reg_rtx (XFmode);
15774   temp = standard_80387_constant_rtx (6); /* fldl2t */
15775   emit_move_insn (operands[3], temp);
15776   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15779 (define_expand "exp10df2"
15780   [(set (match_dup 2)
15781         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15782    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15783    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15784    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15785    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15786    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15787    (parallel [(set (match_dup 10)
15788                    (unspec:XF [(match_dup 9) (match_dup 5)]
15789                               UNSPEC_FSCALE_FRACT))
15790               (set (match_dup 11)
15791                    (unspec:XF [(match_dup 9) (match_dup 5)]
15792                               UNSPEC_FSCALE_EXP))])
15793    (set (match_operand:DF 0 "register_operand" "")
15794         (float_truncate:DF (match_dup 10)))]
15795   "TARGET_USE_FANCY_MATH_387
15796    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15797    && flag_unsafe_math_optimizations"
15799   rtx temp;
15800   int i;
15802   for (i=2; i<12; i++)
15803     operands[i] = gen_reg_rtx (XFmode);
15804   temp = standard_80387_constant_rtx (6); /* fldl2t */
15805   emit_move_insn (operands[3], temp);
15806   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
15809 (define_expand "exp10xf2"
15810   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15811                                (match_dup 2)))
15812    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15813    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15814    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15815    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15816    (parallel [(set (match_operand:XF 0 "register_operand" "")
15817                    (unspec:XF [(match_dup 8) (match_dup 4)]
15818                               UNSPEC_FSCALE_FRACT))
15819               (set (match_dup 9)
15820                    (unspec:XF [(match_dup 8) (match_dup 4)]
15821                               UNSPEC_FSCALE_EXP))])]
15822   "TARGET_USE_FANCY_MATH_387
15823    && flag_unsafe_math_optimizations"
15825   rtx temp;
15826   int i;
15828   for (i=2; i<10; i++)
15829     operands[i] = gen_reg_rtx (XFmode);
15830   temp = standard_80387_constant_rtx (6); /* fldl2t */
15831   emit_move_insn (operands[2], temp);
15832   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15835 (define_expand "exp2sf2"
15836   [(set (match_dup 2)
15837         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15838    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15839    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15840    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15841    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15842    (parallel [(set (match_dup 8)
15843                    (unspec:XF [(match_dup 7) (match_dup 3)]
15844                               UNSPEC_FSCALE_FRACT))
15845               (set (match_dup 9)
15846                    (unspec:XF [(match_dup 7) (match_dup 3)]
15847                               UNSPEC_FSCALE_EXP))])
15848    (set (match_operand:SF 0 "register_operand" "")
15849         (float_truncate:SF (match_dup 8)))]
15850   "TARGET_USE_FANCY_MATH_387
15851    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15852    && flag_unsafe_math_optimizations"
15854   int i;
15856   for (i=2; i<10; i++)
15857     operands[i] = gen_reg_rtx (XFmode);
15858   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15861 (define_expand "exp2df2"
15862   [(set (match_dup 2)
15863         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15864    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15865    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15866    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15867    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15868    (parallel [(set (match_dup 8)
15869                    (unspec:XF [(match_dup 7) (match_dup 3)]
15870                               UNSPEC_FSCALE_FRACT))
15871               (set (match_dup 9)
15872                    (unspec:XF [(match_dup 7) (match_dup 3)]
15873                               UNSPEC_FSCALE_EXP))])
15874    (set (match_operand:DF 0 "register_operand" "")
15875         (float_truncate:DF (match_dup 8)))]
15876   "TARGET_USE_FANCY_MATH_387
15877    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15878    && flag_unsafe_math_optimizations"
15880   int i;
15882   for (i=2; i<10; i++)
15883     operands[i] = gen_reg_rtx (XFmode);
15884   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15887 (define_expand "exp2xf2"
15888   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
15889    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15890    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15891    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15892    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15893    (parallel [(set (match_operand:XF 0 "register_operand" "")
15894                    (unspec:XF [(match_dup 7) (match_dup 3)]
15895                               UNSPEC_FSCALE_FRACT))
15896               (set (match_dup 8)
15897                    (unspec:XF [(match_dup 7) (match_dup 3)]
15898                               UNSPEC_FSCALE_EXP))])]
15899   "TARGET_USE_FANCY_MATH_387
15900    && flag_unsafe_math_optimizations"
15902   int i;
15904   for (i=2; i<9; i++)
15905     operands[i] = gen_reg_rtx (XFmode);
15906   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
15909 (define_expand "expm1df2"
15910   [(set (match_dup 2)
15911         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15912    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15913    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15914    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15915    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15916    (parallel [(set (match_dup 8)
15917                    (unspec:XF [(match_dup 7) (match_dup 5)]
15918                               UNSPEC_FSCALE_FRACT))
15919                    (set (match_dup 9)
15920                    (unspec:XF [(match_dup 7) (match_dup 5)]
15921                               UNSPEC_FSCALE_EXP))])
15922    (parallel [(set (match_dup 11)
15923                    (unspec:XF [(match_dup 10) (match_dup 9)]
15924                               UNSPEC_FSCALE_FRACT))
15925               (set (match_dup 12)
15926                    (unspec:XF [(match_dup 10) (match_dup 9)]
15927                               UNSPEC_FSCALE_EXP))])
15928    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15929    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15930    (set (match_operand:DF 0 "register_operand" "")
15931         (float_truncate:DF (match_dup 14)))]
15932   "TARGET_USE_FANCY_MATH_387
15933    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15934    && flag_unsafe_math_optimizations"
15936   rtx temp;
15937   int i;
15939   for (i=2; i<15; i++)
15940     operands[i] = gen_reg_rtx (XFmode);
15941   temp = standard_80387_constant_rtx (5); /* fldl2e */
15942   emit_move_insn (operands[3], temp);
15943   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
15946 (define_expand "expm1sf2"
15947   [(set (match_dup 2)
15948         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15949    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15950    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15951    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15952    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15953    (parallel [(set (match_dup 8)
15954                    (unspec:XF [(match_dup 7) (match_dup 5)]
15955                               UNSPEC_FSCALE_FRACT))
15956                    (set (match_dup 9)
15957                    (unspec:XF [(match_dup 7) (match_dup 5)]
15958                               UNSPEC_FSCALE_EXP))])
15959    (parallel [(set (match_dup 11)
15960                    (unspec:XF [(match_dup 10) (match_dup 9)]
15961                               UNSPEC_FSCALE_FRACT))
15962               (set (match_dup 12)
15963                    (unspec:XF [(match_dup 10) (match_dup 9)]
15964                               UNSPEC_FSCALE_EXP))])
15965    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
15966    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
15967    (set (match_operand:SF 0 "register_operand" "")
15968         (float_truncate:SF (match_dup 14)))]
15969   "TARGET_USE_FANCY_MATH_387
15970    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15971    && flag_unsafe_math_optimizations"
15973   rtx temp;
15974   int i;
15976   for (i=2; i<15; i++)
15977     operands[i] = gen_reg_rtx (XFmode);
15978   temp = standard_80387_constant_rtx (5); /* fldl2e */
15979   emit_move_insn (operands[3], temp);
15980   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
15983 (define_expand "expm1xf2"
15984   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15985                                (match_dup 2)))
15986    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15987    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15988    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15989    (parallel [(set (match_dup 7)
15990                    (unspec:XF [(match_dup 6) (match_dup 4)]
15991                               UNSPEC_FSCALE_FRACT))
15992                    (set (match_dup 8)
15993                    (unspec:XF [(match_dup 6) (match_dup 4)]
15994                               UNSPEC_FSCALE_EXP))])
15995    (parallel [(set (match_dup 10)
15996                    (unspec:XF [(match_dup 9) (match_dup 8)]
15997                               UNSPEC_FSCALE_FRACT))
15998               (set (match_dup 11)
15999                    (unspec:XF [(match_dup 9) (match_dup 8)]
16000                               UNSPEC_FSCALE_EXP))])
16001    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16002    (set (match_operand:XF 0 "register_operand" "")
16003         (plus:XF (match_dup 12) (match_dup 7)))]
16004   "TARGET_USE_FANCY_MATH_387
16005    && flag_unsafe_math_optimizations"
16007   rtx temp;
16008   int i;
16010   for (i=2; i<13; i++)
16011     operands[i] = gen_reg_rtx (XFmode);
16012   temp = standard_80387_constant_rtx (5); /* fldl2e */
16013   emit_move_insn (operands[2], temp);
16014   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16017 (define_expand "ldexpdf3"
16018   [(set (match_dup 3)
16019         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16020    (set (match_dup 4)
16021         (float:XF (match_operand:SI 2 "register_operand" "")))
16022    (parallel [(set (match_dup 5)
16023                    (unspec:XF [(match_dup 3) (match_dup 4)]
16024                               UNSPEC_FSCALE_FRACT))
16025               (set (match_dup 6)
16026                    (unspec:XF [(match_dup 3) (match_dup 4)]
16027                               UNSPEC_FSCALE_EXP))])
16028    (set (match_operand:DF 0 "register_operand" "")
16029         (float_truncate:DF (match_dup 5)))]
16030   "TARGET_USE_FANCY_MATH_387
16031    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16032    && flag_unsafe_math_optimizations"
16034   int i;
16036   for (i=3; i<7; i++)
16037     operands[i] = gen_reg_rtx (XFmode);
16040 (define_expand "ldexpsf3"
16041   [(set (match_dup 3)
16042         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16043    (set (match_dup 4)
16044         (float:XF (match_operand:SI 2 "register_operand" "")))
16045    (parallel [(set (match_dup 5)
16046                    (unspec:XF [(match_dup 3) (match_dup 4)]
16047                               UNSPEC_FSCALE_FRACT))
16048               (set (match_dup 6)
16049                    (unspec:XF [(match_dup 3) (match_dup 4)]
16050                               UNSPEC_FSCALE_EXP))])
16051    (set (match_operand:SF 0 "register_operand" "")
16052         (float_truncate:SF (match_dup 5)))]
16053   "TARGET_USE_FANCY_MATH_387
16054    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16055    && flag_unsafe_math_optimizations"
16057   int i;
16059   for (i=3; i<7; i++)
16060     operands[i] = gen_reg_rtx (XFmode);
16063 (define_expand "ldexpxf3"
16064   [(set (match_dup 3)
16065         (float:XF (match_operand:SI 2 "register_operand" "")))
16066    (parallel [(set (match_operand:XF 0 " register_operand" "")
16067                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16068                                (match_dup 3)]
16069                               UNSPEC_FSCALE_FRACT))
16070               (set (match_dup 4)
16071                    (unspec:XF [(match_dup 1) (match_dup 3)]
16072                               UNSPEC_FSCALE_EXP))])]
16073   "TARGET_USE_FANCY_MATH_387
16074    && flag_unsafe_math_optimizations"
16076   int i;
16078   for (i=3; i<5; i++)
16079     operands[i] = gen_reg_rtx (XFmode);
16083 (define_insn "frndintxf2"
16084   [(set (match_operand:XF 0 "register_operand" "=f")
16085         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16086          UNSPEC_FRNDINT))]
16087   "TARGET_USE_FANCY_MATH_387
16088    && flag_unsafe_math_optimizations"
16089   "frndint"
16090   [(set_attr "type" "fpspc")
16091    (set_attr "mode" "XF")])
16093 (define_expand "rintdf2"
16094   [(use (match_operand:DF 0 "register_operand" ""))
16095    (use (match_operand:DF 1 "register_operand" ""))]
16096   "TARGET_USE_FANCY_MATH_387
16097    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16098    && flag_unsafe_math_optimizations"
16100   rtx op0 = gen_reg_rtx (XFmode);
16101   rtx op1 = gen_reg_rtx (XFmode);
16103   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16104   emit_insn (gen_frndintxf2 (op0, op1));
16106   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16107   DONE;
16110 (define_expand "rintsf2"
16111   [(use (match_operand:SF 0 "register_operand" ""))
16112    (use (match_operand:SF 1 "register_operand" ""))]
16113   "TARGET_USE_FANCY_MATH_387
16114    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16115    && flag_unsafe_math_optimizations"
16117   rtx op0 = gen_reg_rtx (XFmode);
16118   rtx op1 = gen_reg_rtx (XFmode);
16120   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16121   emit_insn (gen_frndintxf2 (op0, op1));
16123   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16124   DONE;
16127 (define_expand "rintxf2"
16128   [(use (match_operand:XF 0 "register_operand" ""))
16129    (use (match_operand:XF 1 "register_operand" ""))]
16130   "TARGET_USE_FANCY_MATH_387
16131    && flag_unsafe_math_optimizations"
16133   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16134   DONE;
16137 (define_insn "fistdi2"
16138   [(set (match_operand:DI 0 "memory_operand" "=m")
16139         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16140          UNSPEC_FIST))
16141    (clobber (match_scratch:XF 2 "=&1f"))]
16142   "TARGET_USE_FANCY_MATH_387
16143    && flag_unsafe_math_optimizations"
16144   "* return output_fix_trunc (insn, operands, 0);"
16145   [(set_attr "type" "fpspc")
16146    (set_attr "mode" "DI")])
16148 (define_insn "fistdi2_with_temp"
16149   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16150         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16151          UNSPEC_FIST))
16152    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16153    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16154   "TARGET_USE_FANCY_MATH_387
16155    && flag_unsafe_math_optimizations"
16156   "#"
16157   [(set_attr "type" "fpspc")
16158    (set_attr "mode" "DI")])
16160 (define_split 
16161   [(set (match_operand:DI 0 "register_operand" "")
16162         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16163          UNSPEC_FIST))
16164    (clobber (match_operand:DI 2 "memory_operand" ""))
16165    (clobber (match_scratch 3 ""))]
16166   "reload_completed"
16167   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16168               (clobber (match_dup 3))])
16169    (set (match_dup 0) (match_dup 2))]
16170   "")
16172 (define_split 
16173   [(set (match_operand:DI 0 "memory_operand" "")
16174         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16175          UNSPEC_FIST))
16176    (clobber (match_operand:DI 2 "memory_operand" ""))
16177    (clobber (match_scratch 3 ""))]
16178   "reload_completed"
16179   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16180               (clobber (match_dup 3))])]
16181   "")
16183 (define_insn "fist<mode>2"
16184   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16185         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16186          UNSPEC_FIST))]
16187   "TARGET_USE_FANCY_MATH_387
16188    && flag_unsafe_math_optimizations"
16189   "* return output_fix_trunc (insn, operands, 0);"
16190   [(set_attr "type" "fpspc")
16191    (set_attr "mode" "<MODE>")])
16193 (define_insn "fist<mode>2_with_temp"
16194   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16195         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16196          UNSPEC_FIST))
16197    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16198   "TARGET_USE_FANCY_MATH_387
16199    && flag_unsafe_math_optimizations"
16200   "#"
16201   [(set_attr "type" "fpspc")
16202    (set_attr "mode" "<MODE>")])
16204 (define_split 
16205   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16206         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16207          UNSPEC_FIST))
16208    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16209   "reload_completed"
16210   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16211                        UNSPEC_FIST))
16212    (set (match_dup 0) (match_dup 2))]
16213   "")
16215 (define_split 
16216   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16217         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16218          UNSPEC_FIST))
16219    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16220   "reload_completed"
16221   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16222                        UNSPEC_FIST))]
16223   "")
16225 (define_expand "lrint<mode>2"
16226   [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16227    (use (match_operand:XF 1 "register_operand" ""))]
16228   "TARGET_USE_FANCY_MATH_387
16229    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16230    && flag_unsafe_math_optimizations"
16232   if (memory_operand (operands[0], VOIDmode))
16233     emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16234   else
16235     {
16236       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16237       emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16238                                             operands[2]));
16239     }
16240   DONE;
16243 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16244 (define_insn_and_split "frndintxf2_floor"
16245   [(set (match_operand:XF 0 "register_operand" "=f")
16246         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16247          UNSPEC_FRNDINT_FLOOR))
16248    (clobber (reg:CC FLAGS_REG))]
16249   "TARGET_USE_FANCY_MATH_387
16250    && flag_unsafe_math_optimizations
16251    && !(reload_completed || reload_in_progress)"
16252   "#"
16253   "&& 1"
16254   [(const_int 0)]
16256   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16258   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16259   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16261   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16262                                         operands[2], operands[3]));
16263   DONE;
16265   [(set_attr "type" "frndint")
16266    (set_attr "i387_cw" "floor")
16267    (set_attr "mode" "XF")])
16269 (define_insn "frndintxf2_floor_i387"
16270   [(set (match_operand:XF 0 "register_operand" "=f")
16271         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16272          UNSPEC_FRNDINT_FLOOR))
16273    (use (match_operand:HI 2 "memory_operand" "m"))
16274    (use (match_operand:HI 3 "memory_operand" "m"))]
16275   "TARGET_USE_FANCY_MATH_387
16276    && flag_unsafe_math_optimizations"
16277   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16278   [(set_attr "type" "frndint")
16279    (set_attr "i387_cw" "floor")
16280    (set_attr "mode" "XF")])
16282 (define_expand "floorxf2"
16283   [(use (match_operand:XF 0 "register_operand" ""))
16284    (use (match_operand:XF 1 "register_operand" ""))]
16285   "TARGET_USE_FANCY_MATH_387
16286    && flag_unsafe_math_optimizations"
16288   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16289   DONE;
16292 (define_expand "floordf2"
16293   [(use (match_operand:DF 0 "register_operand" ""))
16294    (use (match_operand:DF 1 "register_operand" ""))]
16295   "TARGET_USE_FANCY_MATH_387
16296    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16297    && flag_unsafe_math_optimizations"
16299   rtx op0 = gen_reg_rtx (XFmode);
16300   rtx op1 = gen_reg_rtx (XFmode);
16302   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16303   emit_insn (gen_frndintxf2_floor (op0, op1));
16305   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16306   DONE;
16309 (define_expand "floorsf2"
16310   [(use (match_operand:SF 0 "register_operand" ""))
16311    (use (match_operand:SF 1 "register_operand" ""))]
16312   "TARGET_USE_FANCY_MATH_387
16313    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16314    && flag_unsafe_math_optimizations"
16316   rtx op0 = gen_reg_rtx (XFmode);
16317   rtx op1 = gen_reg_rtx (XFmode);
16319   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16320   emit_insn (gen_frndintxf2_floor (op0, op1));
16322   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16323   DONE;
16326 (define_insn_and_split "*fist<mode>2_floor_1"
16327   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16328         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16329          UNSPEC_FIST_FLOOR))
16330    (clobber (reg:CC FLAGS_REG))]
16331   "TARGET_USE_FANCY_MATH_387
16332    && flag_unsafe_math_optimizations
16333    && !(reload_completed || reload_in_progress)"
16334   "#"
16335   "&& 1"
16336   [(const_int 0)]
16338   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16340   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16341   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16342   if (memory_operand (operands[0], VOIDmode))
16343     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16344                                       operands[2], operands[3]));
16345   else
16346     {
16347       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16348       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16349                                                   operands[2], operands[3],
16350                                                   operands[4]));
16351     }
16352   DONE;
16354   [(set_attr "type" "fistp")
16355    (set_attr "i387_cw" "floor")
16356    (set_attr "mode" "<MODE>")])
16358 (define_insn "fistdi2_floor"
16359   [(set (match_operand:DI 0 "memory_operand" "=m")
16360         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16361          UNSPEC_FIST_FLOOR))
16362    (use (match_operand:HI 2 "memory_operand" "m"))
16363    (use (match_operand:HI 3 "memory_operand" "m"))
16364    (clobber (match_scratch:XF 4 "=&1f"))]
16365   "TARGET_USE_FANCY_MATH_387
16366    && flag_unsafe_math_optimizations"
16367   "* return output_fix_trunc (insn, operands, 0);"
16368   [(set_attr "type" "fistp")
16369    (set_attr "i387_cw" "floor")
16370    (set_attr "mode" "DI")])
16372 (define_insn "fistdi2_floor_with_temp"
16373   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16374         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16375          UNSPEC_FIST_FLOOR))
16376    (use (match_operand:HI 2 "memory_operand" "m,m"))
16377    (use (match_operand:HI 3 "memory_operand" "m,m"))
16378    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16379    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16380   "TARGET_USE_FANCY_MATH_387
16381    && flag_unsafe_math_optimizations"
16382   "#"
16383   [(set_attr "type" "fistp")
16384    (set_attr "i387_cw" "floor")
16385    (set_attr "mode" "DI")])
16387 (define_split 
16388   [(set (match_operand:DI 0 "register_operand" "")
16389         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16390          UNSPEC_FIST_FLOOR))
16391    (use (match_operand:HI 2 "memory_operand" ""))
16392    (use (match_operand:HI 3 "memory_operand" ""))
16393    (clobber (match_operand:DI 4 "memory_operand" ""))
16394    (clobber (match_scratch 5 ""))]
16395   "reload_completed"
16396   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16397               (use (match_dup 2))
16398               (use (match_dup 3))
16399               (clobber (match_dup 5))])
16400    (set (match_dup 0) (match_dup 4))]
16401   "")
16403 (define_split 
16404   [(set (match_operand:DI 0 "memory_operand" "")
16405         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16406          UNSPEC_FIST_FLOOR))
16407    (use (match_operand:HI 2 "memory_operand" ""))
16408    (use (match_operand:HI 3 "memory_operand" ""))
16409    (clobber (match_operand:DI 4 "memory_operand" ""))
16410    (clobber (match_scratch 5 ""))]
16411   "reload_completed"
16412   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16413               (use (match_dup 2))
16414               (use (match_dup 3))
16415               (clobber (match_dup 5))])]
16416   "")
16418 (define_insn "fist<mode>2_floor"
16419   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16420         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16421          UNSPEC_FIST_FLOOR))
16422    (use (match_operand:HI 2 "memory_operand" "m"))
16423    (use (match_operand:HI 3 "memory_operand" "m"))]
16424   "TARGET_USE_FANCY_MATH_387
16425    && flag_unsafe_math_optimizations"
16426   "* return output_fix_trunc (insn, operands, 0);"
16427   [(set_attr "type" "fistp")
16428    (set_attr "i387_cw" "floor")
16429    (set_attr "mode" "<MODE>")])
16431 (define_insn "fist<mode>2_floor_with_temp"
16432   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16433         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16434          UNSPEC_FIST_FLOOR))
16435    (use (match_operand:HI 2 "memory_operand" "m,m"))
16436    (use (match_operand:HI 3 "memory_operand" "m,m"))
16437    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16438   "TARGET_USE_FANCY_MATH_387
16439    && flag_unsafe_math_optimizations"
16440   "#"
16441   [(set_attr "type" "fistp")
16442    (set_attr "i387_cw" "floor")
16443    (set_attr "mode" "<MODE>")])
16445 (define_split 
16446   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16447         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16448          UNSPEC_FIST_FLOOR))
16449    (use (match_operand:HI 2 "memory_operand" ""))
16450    (use (match_operand:HI 3 "memory_operand" ""))
16451    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16452   "reload_completed"
16453   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16454                                   UNSPEC_FIST_FLOOR))
16455               (use (match_dup 2))
16456               (use (match_dup 3))])
16457    (set (match_dup 0) (match_dup 4))]
16458   "")
16460 (define_split 
16461   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16462         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16463          UNSPEC_FIST_FLOOR))
16464    (use (match_operand:HI 2 "memory_operand" ""))
16465    (use (match_operand:HI 3 "memory_operand" ""))
16466    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16467   "reload_completed"
16468   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16469                                   UNSPEC_FIST_FLOOR))
16470               (use (match_dup 2))
16471               (use (match_dup 3))])]
16472   "")
16474 (define_expand "lfloor<mode>2"
16475   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16476                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16477                     UNSPEC_FIST_FLOOR))
16478               (clobber (reg:CC FLAGS_REG))])]
16479   "TARGET_USE_FANCY_MATH_387
16480    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16481    && flag_unsafe_math_optimizations"
16482   "")
16484 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16485 (define_insn_and_split "frndintxf2_ceil"
16486   [(set (match_operand:XF 0 "register_operand" "=f")
16487         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16488          UNSPEC_FRNDINT_CEIL))
16489    (clobber (reg:CC FLAGS_REG))]
16490   "TARGET_USE_FANCY_MATH_387
16491    && flag_unsafe_math_optimizations
16492    && !(reload_completed || reload_in_progress)"
16493   "#"
16494   "&& 1"
16495   [(const_int 0)]
16497   ix86_optimize_mode_switching[I387_CEIL] = 1;
16499   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16500   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16502   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16503                                        operands[2], operands[3]));
16504   DONE;
16506   [(set_attr "type" "frndint")
16507    (set_attr "i387_cw" "ceil")
16508    (set_attr "mode" "XF")])
16510 (define_insn "frndintxf2_ceil_i387"
16511   [(set (match_operand:XF 0 "register_operand" "=f")
16512         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16513          UNSPEC_FRNDINT_CEIL))
16514    (use (match_operand:HI 2 "memory_operand" "m"))
16515    (use (match_operand:HI 3 "memory_operand" "m"))]
16516   "TARGET_USE_FANCY_MATH_387
16517    && flag_unsafe_math_optimizations"
16518   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16519   [(set_attr "type" "frndint")
16520    (set_attr "i387_cw" "ceil")
16521    (set_attr "mode" "XF")])
16523 (define_expand "ceilxf2"
16524   [(use (match_operand:XF 0 "register_operand" ""))
16525    (use (match_operand:XF 1 "register_operand" ""))]
16526   "TARGET_USE_FANCY_MATH_387
16527    && flag_unsafe_math_optimizations"
16529   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16530   DONE;
16533 (define_expand "ceildf2"
16534   [(use (match_operand:DF 0 "register_operand" ""))
16535    (use (match_operand:DF 1 "register_operand" ""))]
16536   "TARGET_USE_FANCY_MATH_387
16537    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16538    && flag_unsafe_math_optimizations"
16540   rtx op0 = gen_reg_rtx (XFmode);
16541   rtx op1 = gen_reg_rtx (XFmode);
16543   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16544   emit_insn (gen_frndintxf2_ceil (op0, op1));
16546   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16547   DONE;
16550 (define_expand "ceilsf2"
16551   [(use (match_operand:SF 0 "register_operand" ""))
16552    (use (match_operand:SF 1 "register_operand" ""))]
16553   "TARGET_USE_FANCY_MATH_387
16554    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16555    && flag_unsafe_math_optimizations"
16557   rtx op0 = gen_reg_rtx (XFmode);
16558   rtx op1 = gen_reg_rtx (XFmode);
16560   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16561   emit_insn (gen_frndintxf2_ceil (op0, op1));
16563   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16564   DONE;
16567 (define_insn_and_split "*fist<mode>2_ceil_1"
16568   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16569         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16570          UNSPEC_FIST_CEIL))
16571    (clobber (reg:CC FLAGS_REG))]
16572   "TARGET_USE_FANCY_MATH_387
16573    && flag_unsafe_math_optimizations
16574    && !(reload_completed || reload_in_progress)"
16575   "#"
16576   "&& 1"
16577   [(const_int 0)]
16579   ix86_optimize_mode_switching[I387_CEIL] = 1;
16581   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16582   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16583   if (memory_operand (operands[0], VOIDmode))
16584     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16585                                      operands[2], operands[3]));
16586   else
16587     {
16588       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16589       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16590                                                  operands[2], operands[3],
16591                                                  operands[4]));
16592     }
16593   DONE;
16595   [(set_attr "type" "fistp")
16596    (set_attr "i387_cw" "ceil")
16597    (set_attr "mode" "<MODE>")])
16599 (define_insn "fistdi2_ceil"
16600   [(set (match_operand:DI 0 "memory_operand" "=m")
16601         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16602          UNSPEC_FIST_CEIL))
16603    (use (match_operand:HI 2 "memory_operand" "m"))
16604    (use (match_operand:HI 3 "memory_operand" "m"))
16605    (clobber (match_scratch:XF 4 "=&1f"))]
16606   "TARGET_USE_FANCY_MATH_387
16607    && flag_unsafe_math_optimizations"
16608   "* return output_fix_trunc (insn, operands, 0);"
16609   [(set_attr "type" "fistp")
16610    (set_attr "i387_cw" "ceil")
16611    (set_attr "mode" "DI")])
16613 (define_insn "fistdi2_ceil_with_temp"
16614   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16615         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16616          UNSPEC_FIST_CEIL))
16617    (use (match_operand:HI 2 "memory_operand" "m,m"))
16618    (use (match_operand:HI 3 "memory_operand" "m,m"))
16619    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16620    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16621   "TARGET_USE_FANCY_MATH_387
16622    && flag_unsafe_math_optimizations"
16623   "#"
16624   [(set_attr "type" "fistp")
16625    (set_attr "i387_cw" "ceil")
16626    (set_attr "mode" "DI")])
16628 (define_split 
16629   [(set (match_operand:DI 0 "register_operand" "")
16630         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16631          UNSPEC_FIST_CEIL))
16632    (use (match_operand:HI 2 "memory_operand" ""))
16633    (use (match_operand:HI 3 "memory_operand" ""))
16634    (clobber (match_operand:DI 4 "memory_operand" ""))
16635    (clobber (match_scratch 5 ""))]
16636   "reload_completed"
16637   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16638               (use (match_dup 2))
16639               (use (match_dup 3))
16640               (clobber (match_dup 5))])
16641    (set (match_dup 0) (match_dup 4))]
16642   "")
16644 (define_split 
16645   [(set (match_operand:DI 0 "memory_operand" "")
16646         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16647          UNSPEC_FIST_CEIL))
16648    (use (match_operand:HI 2 "memory_operand" ""))
16649    (use (match_operand:HI 3 "memory_operand" ""))
16650    (clobber (match_operand:DI 4 "memory_operand" ""))
16651    (clobber (match_scratch 5 ""))]
16652   "reload_completed"
16653   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16654               (use (match_dup 2))
16655               (use (match_dup 3))
16656               (clobber (match_dup 5))])]
16657   "")
16659 (define_insn "fist<mode>2_ceil"
16660   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16661         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16662          UNSPEC_FIST_CEIL))
16663    (use (match_operand:HI 2 "memory_operand" "m"))
16664    (use (match_operand:HI 3 "memory_operand" "m"))]
16665   "TARGET_USE_FANCY_MATH_387
16666    && flag_unsafe_math_optimizations"
16667   "* return output_fix_trunc (insn, operands, 0);"
16668   [(set_attr "type" "fistp")
16669    (set_attr "i387_cw" "ceil")
16670    (set_attr "mode" "<MODE>")])
16672 (define_insn "fist<mode>2_ceil_with_temp"
16673   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16674         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16675          UNSPEC_FIST_CEIL))
16676    (use (match_operand:HI 2 "memory_operand" "m,m"))
16677    (use (match_operand:HI 3 "memory_operand" "m,m"))
16678    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16679   "TARGET_USE_FANCY_MATH_387
16680    && flag_unsafe_math_optimizations"
16681   "#"
16682   [(set_attr "type" "fistp")
16683    (set_attr "i387_cw" "ceil")
16684    (set_attr "mode" "<MODE>")])
16686 (define_split 
16687   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16688         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16689          UNSPEC_FIST_CEIL))
16690    (use (match_operand:HI 2 "memory_operand" ""))
16691    (use (match_operand:HI 3 "memory_operand" ""))
16692    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16693   "reload_completed"
16694   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16695                                   UNSPEC_FIST_CEIL))
16696               (use (match_dup 2))
16697               (use (match_dup 3))])
16698    (set (match_dup 0) (match_dup 4))]
16699   "")
16701 (define_split 
16702   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16703         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16704          UNSPEC_FIST_CEIL))
16705    (use (match_operand:HI 2 "memory_operand" ""))
16706    (use (match_operand:HI 3 "memory_operand" ""))
16707    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16708   "reload_completed"
16709   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16710                                   UNSPEC_FIST_CEIL))
16711               (use (match_dup 2))
16712               (use (match_dup 3))])]
16713   "")
16715 (define_expand "lceil<mode>2"
16716   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16717                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16718                     UNSPEC_FIST_CEIL))
16719               (clobber (reg:CC FLAGS_REG))])]
16720   "TARGET_USE_FANCY_MATH_387
16721    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16722    && flag_unsafe_math_optimizations"
16723   "")
16725 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16726 (define_insn_and_split "frndintxf2_trunc"
16727   [(set (match_operand:XF 0 "register_operand" "=f")
16728         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16729          UNSPEC_FRNDINT_TRUNC))
16730    (clobber (reg:CC FLAGS_REG))]
16731   "TARGET_USE_FANCY_MATH_387
16732    && flag_unsafe_math_optimizations
16733    && !(reload_completed || reload_in_progress)"
16734   "#"
16735   "&& 1"
16736   [(const_int 0)]
16738   ix86_optimize_mode_switching[I387_TRUNC] = 1;
16740   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16741   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
16743   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16744                                         operands[2], operands[3]));
16745   DONE;
16747   [(set_attr "type" "frndint")
16748    (set_attr "i387_cw" "trunc")
16749    (set_attr "mode" "XF")])
16751 (define_insn "frndintxf2_trunc_i387"
16752   [(set (match_operand:XF 0 "register_operand" "=f")
16753         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16754          UNSPEC_FRNDINT_TRUNC))
16755    (use (match_operand:HI 2 "memory_operand" "m"))
16756    (use (match_operand:HI 3 "memory_operand" "m"))]
16757   "TARGET_USE_FANCY_MATH_387
16758    && flag_unsafe_math_optimizations"
16759   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16760   [(set_attr "type" "frndint")
16761    (set_attr "i387_cw" "trunc")
16762    (set_attr "mode" "XF")])
16764 (define_expand "btruncxf2"
16765   [(use (match_operand:XF 0 "register_operand" ""))
16766    (use (match_operand:XF 1 "register_operand" ""))]
16767   "TARGET_USE_FANCY_MATH_387
16768    && flag_unsafe_math_optimizations"
16770   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16771   DONE;
16774 (define_expand "btruncdf2"
16775   [(use (match_operand:DF 0 "register_operand" ""))
16776    (use (match_operand:DF 1 "register_operand" ""))]
16777   "TARGET_USE_FANCY_MATH_387
16778    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16779    && flag_unsafe_math_optimizations"
16781   rtx op0 = gen_reg_rtx (XFmode);
16782   rtx op1 = gen_reg_rtx (XFmode);
16784   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16785   emit_insn (gen_frndintxf2_trunc (op0, op1));
16787   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16788   DONE;
16791 (define_expand "btruncsf2"
16792   [(use (match_operand:SF 0 "register_operand" ""))
16793    (use (match_operand:SF 1 "register_operand" ""))]
16794   "TARGET_USE_FANCY_MATH_387
16795    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16796    && flag_unsafe_math_optimizations"
16798   rtx op0 = gen_reg_rtx (XFmode);
16799   rtx op1 = gen_reg_rtx (XFmode);
16801   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16802   emit_insn (gen_frndintxf2_trunc (op0, op1));
16804   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16805   DONE;
16808 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16809 (define_insn_and_split "frndintxf2_mask_pm"
16810   [(set (match_operand:XF 0 "register_operand" "=f")
16811         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16812          UNSPEC_FRNDINT_MASK_PM))
16813    (clobber (reg:CC FLAGS_REG))]
16814   "TARGET_USE_FANCY_MATH_387
16815    && flag_unsafe_math_optimizations
16816    && !(reload_completed || reload_in_progress)"
16817   "#"
16818   "&& 1"
16819   [(const_int 0)]
16821   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16823   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16824   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16826   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16827                                           operands[2], operands[3]));
16828   DONE;
16830   [(set_attr "type" "frndint")
16831    (set_attr "i387_cw" "mask_pm")
16832    (set_attr "mode" "XF")])
16834 (define_insn "frndintxf2_mask_pm_i387"
16835   [(set (match_operand:XF 0 "register_operand" "=f")
16836         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16837          UNSPEC_FRNDINT_MASK_PM))
16838    (use (match_operand:HI 2 "memory_operand" "m"))
16839    (use (match_operand:HI 3 "memory_operand" "m"))]
16840   "TARGET_USE_FANCY_MATH_387
16841    && flag_unsafe_math_optimizations"
16842   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16843   [(set_attr "type" "frndint")
16844    (set_attr "i387_cw" "mask_pm")
16845    (set_attr "mode" "XF")])
16847 (define_expand "nearbyintxf2"
16848   [(use (match_operand:XF 0 "register_operand" ""))
16849    (use (match_operand:XF 1 "register_operand" ""))]
16850   "TARGET_USE_FANCY_MATH_387
16851    && flag_unsafe_math_optimizations"
16853   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16855   DONE;
16858 (define_expand "nearbyintdf2"
16859   [(use (match_operand:DF 0 "register_operand" ""))
16860    (use (match_operand:DF 1 "register_operand" ""))]
16861   "TARGET_USE_FANCY_MATH_387
16862    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16863    && flag_unsafe_math_optimizations"
16865   rtx op0 = gen_reg_rtx (XFmode);
16866   rtx op1 = gen_reg_rtx (XFmode);
16868   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16869   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16871   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16872   DONE;
16875 (define_expand "nearbyintsf2"
16876   [(use (match_operand:SF 0 "register_operand" ""))
16877    (use (match_operand:SF 1 "register_operand" ""))]
16878   "TARGET_USE_FANCY_MATH_387
16879    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16880    && flag_unsafe_math_optimizations"
16882   rtx op0 = gen_reg_rtx (XFmode);
16883   rtx op1 = gen_reg_rtx (XFmode);
16885   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16886   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16888   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16889   DONE;
16893 ;; Block operation instructions
16895 (define_insn "cld"
16896  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16897  ""
16898  "cld"
16899   [(set_attr "type" "cld")])
16901 (define_expand "movmemsi"
16902   [(use (match_operand:BLK 0 "memory_operand" ""))
16903    (use (match_operand:BLK 1 "memory_operand" ""))
16904    (use (match_operand:SI 2 "nonmemory_operand" ""))
16905    (use (match_operand:SI 3 "const_int_operand" ""))]
16906   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
16908  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16909    DONE;
16910  else
16911    FAIL;
16914 (define_expand "movmemdi"
16915   [(use (match_operand:BLK 0 "memory_operand" ""))
16916    (use (match_operand:BLK 1 "memory_operand" ""))
16917    (use (match_operand:DI 2 "nonmemory_operand" ""))
16918    (use (match_operand:DI 3 "const_int_operand" ""))]
16919   "TARGET_64BIT"
16921  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16922    DONE;
16923  else
16924    FAIL;
16927 ;; Most CPUs don't like single string operations
16928 ;; Handle this case here to simplify previous expander.
16930 (define_expand "strmov"
16931   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16932    (set (match_operand 1 "memory_operand" "") (match_dup 4))
16933    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16934               (clobber (reg:CC FLAGS_REG))])
16935    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16936               (clobber (reg:CC FLAGS_REG))])]
16937   ""
16939   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16941   /* If .md ever supports :P for Pmode, these can be directly
16942      in the pattern above.  */
16943   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16944   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16946   if (TARGET_SINGLE_STRINGOP || optimize_size)
16947     {
16948       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16949                                       operands[2], operands[3],
16950                                       operands[5], operands[6]));
16951       DONE;
16952     }
16954   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16957 (define_expand "strmov_singleop"
16958   [(parallel [(set (match_operand 1 "memory_operand" "")
16959                    (match_operand 3 "memory_operand" ""))
16960               (set (match_operand 0 "register_operand" "")
16961                    (match_operand 4 "" ""))
16962               (set (match_operand 2 "register_operand" "")
16963                    (match_operand 5 "" ""))
16964               (use (reg:SI DIRFLAG_REG))])]
16965   "TARGET_SINGLE_STRINGOP || optimize_size"
16966   "")
16968 (define_insn "*strmovdi_rex_1"
16969   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16970         (mem:DI (match_operand:DI 3 "register_operand" "1")))
16971    (set (match_operand:DI 0 "register_operand" "=D")
16972         (plus:DI (match_dup 2)
16973                  (const_int 8)))
16974    (set (match_operand:DI 1 "register_operand" "=S")
16975         (plus:DI (match_dup 3)
16976                  (const_int 8)))
16977    (use (reg:SI DIRFLAG_REG))]
16978   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16979   "movsq"
16980   [(set_attr "type" "str")
16981    (set_attr "mode" "DI")
16982    (set_attr "memory" "both")])
16984 (define_insn "*strmovsi_1"
16985   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16986         (mem:SI (match_operand:SI 3 "register_operand" "1")))
16987    (set (match_operand:SI 0 "register_operand" "=D")
16988         (plus:SI (match_dup 2)
16989                  (const_int 4)))
16990    (set (match_operand:SI 1 "register_operand" "=S")
16991         (plus:SI (match_dup 3)
16992                  (const_int 4)))
16993    (use (reg:SI DIRFLAG_REG))]
16994   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16995   "{movsl|movsd}"
16996   [(set_attr "type" "str")
16997    (set_attr "mode" "SI")
16998    (set_attr "memory" "both")])
17000 (define_insn "*strmovsi_rex_1"
17001   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17002         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17003    (set (match_operand:DI 0 "register_operand" "=D")
17004         (plus:DI (match_dup 2)
17005                  (const_int 4)))
17006    (set (match_operand:DI 1 "register_operand" "=S")
17007         (plus:DI (match_dup 3)
17008                  (const_int 4)))
17009    (use (reg:SI DIRFLAG_REG))]
17010   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17011   "{movsl|movsd}"
17012   [(set_attr "type" "str")
17013    (set_attr "mode" "SI")
17014    (set_attr "memory" "both")])
17016 (define_insn "*strmovhi_1"
17017   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17018         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17019    (set (match_operand:SI 0 "register_operand" "=D")
17020         (plus:SI (match_dup 2)
17021                  (const_int 2)))
17022    (set (match_operand:SI 1 "register_operand" "=S")
17023         (plus:SI (match_dup 3)
17024                  (const_int 2)))
17025    (use (reg:SI DIRFLAG_REG))]
17026   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17027   "movsw"
17028   [(set_attr "type" "str")
17029    (set_attr "memory" "both")
17030    (set_attr "mode" "HI")])
17032 (define_insn "*strmovhi_rex_1"
17033   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17034         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17035    (set (match_operand:DI 0 "register_operand" "=D")
17036         (plus:DI (match_dup 2)
17037                  (const_int 2)))
17038    (set (match_operand:DI 1 "register_operand" "=S")
17039         (plus:DI (match_dup 3)
17040                  (const_int 2)))
17041    (use (reg:SI DIRFLAG_REG))]
17042   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17043   "movsw"
17044   [(set_attr "type" "str")
17045    (set_attr "memory" "both")
17046    (set_attr "mode" "HI")])
17048 (define_insn "*strmovqi_1"
17049   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17050         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17051    (set (match_operand:SI 0 "register_operand" "=D")
17052         (plus:SI (match_dup 2)
17053                  (const_int 1)))
17054    (set (match_operand:SI 1 "register_operand" "=S")
17055         (plus:SI (match_dup 3)
17056                  (const_int 1)))
17057    (use (reg:SI DIRFLAG_REG))]
17058   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17059   "movsb"
17060   [(set_attr "type" "str")
17061    (set_attr "memory" "both")
17062    (set_attr "mode" "QI")])
17064 (define_insn "*strmovqi_rex_1"
17065   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17066         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17067    (set (match_operand:DI 0 "register_operand" "=D")
17068         (plus:DI (match_dup 2)
17069                  (const_int 1)))
17070    (set (match_operand:DI 1 "register_operand" "=S")
17071         (plus:DI (match_dup 3)
17072                  (const_int 1)))
17073    (use (reg:SI DIRFLAG_REG))]
17074   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17075   "movsb"
17076   [(set_attr "type" "str")
17077    (set_attr "memory" "both")
17078    (set_attr "mode" "QI")])
17080 (define_expand "rep_mov"
17081   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17082               (set (match_operand 0 "register_operand" "")
17083                    (match_operand 5 "" ""))
17084               (set (match_operand 2 "register_operand" "")
17085                    (match_operand 6 "" ""))
17086               (set (match_operand 1 "memory_operand" "")
17087                    (match_operand 3 "memory_operand" ""))
17088               (use (match_dup 4))
17089               (use (reg:SI DIRFLAG_REG))])]
17090   ""
17091   "")
17093 (define_insn "*rep_movdi_rex64"
17094   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17095    (set (match_operand:DI 0 "register_operand" "=D") 
17096         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17097                             (const_int 3))
17098                  (match_operand:DI 3 "register_operand" "0")))
17099    (set (match_operand:DI 1 "register_operand" "=S") 
17100         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17101                  (match_operand:DI 4 "register_operand" "1")))
17102    (set (mem:BLK (match_dup 3))
17103         (mem:BLK (match_dup 4)))
17104    (use (match_dup 5))
17105    (use (reg:SI DIRFLAG_REG))]
17106   "TARGET_64BIT"
17107   "{rep\;movsq|rep movsq}"
17108   [(set_attr "type" "str")
17109    (set_attr "prefix_rep" "1")
17110    (set_attr "memory" "both")
17111    (set_attr "mode" "DI")])
17113 (define_insn "*rep_movsi"
17114   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17115    (set (match_operand:SI 0 "register_operand" "=D") 
17116         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17117                             (const_int 2))
17118                  (match_operand:SI 3 "register_operand" "0")))
17119    (set (match_operand:SI 1 "register_operand" "=S") 
17120         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17121                  (match_operand:SI 4 "register_operand" "1")))
17122    (set (mem:BLK (match_dup 3))
17123         (mem:BLK (match_dup 4)))
17124    (use (match_dup 5))
17125    (use (reg:SI DIRFLAG_REG))]
17126   "!TARGET_64BIT"
17127   "{rep\;movsl|rep movsd}"
17128   [(set_attr "type" "str")
17129    (set_attr "prefix_rep" "1")
17130    (set_attr "memory" "both")
17131    (set_attr "mode" "SI")])
17133 (define_insn "*rep_movsi_rex64"
17134   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17135    (set (match_operand:DI 0 "register_operand" "=D") 
17136         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17137                             (const_int 2))
17138                  (match_operand:DI 3 "register_operand" "0")))
17139    (set (match_operand:DI 1 "register_operand" "=S") 
17140         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17141                  (match_operand:DI 4 "register_operand" "1")))
17142    (set (mem:BLK (match_dup 3))
17143         (mem:BLK (match_dup 4)))
17144    (use (match_dup 5))
17145    (use (reg:SI DIRFLAG_REG))]
17146   "TARGET_64BIT"
17147   "{rep\;movsl|rep movsd}"
17148   [(set_attr "type" "str")
17149    (set_attr "prefix_rep" "1")
17150    (set_attr "memory" "both")
17151    (set_attr "mode" "SI")])
17153 (define_insn "*rep_movqi"
17154   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17155    (set (match_operand:SI 0 "register_operand" "=D") 
17156         (plus:SI (match_operand:SI 3 "register_operand" "0")
17157                  (match_operand:SI 5 "register_operand" "2")))
17158    (set (match_operand:SI 1 "register_operand" "=S") 
17159         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17160    (set (mem:BLK (match_dup 3))
17161         (mem:BLK (match_dup 4)))
17162    (use (match_dup 5))
17163    (use (reg:SI DIRFLAG_REG))]
17164   "!TARGET_64BIT"
17165   "{rep\;movsb|rep movsb}"
17166   [(set_attr "type" "str")
17167    (set_attr "prefix_rep" "1")
17168    (set_attr "memory" "both")
17169    (set_attr "mode" "SI")])
17171 (define_insn "*rep_movqi_rex64"
17172   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17173    (set (match_operand:DI 0 "register_operand" "=D") 
17174         (plus:DI (match_operand:DI 3 "register_operand" "0")
17175                  (match_operand:DI 5 "register_operand" "2")))
17176    (set (match_operand:DI 1 "register_operand" "=S") 
17177         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17178    (set (mem:BLK (match_dup 3))
17179         (mem:BLK (match_dup 4)))
17180    (use (match_dup 5))
17181    (use (reg:SI DIRFLAG_REG))]
17182   "TARGET_64BIT"
17183   "{rep\;movsb|rep movsb}"
17184   [(set_attr "type" "str")
17185    (set_attr "prefix_rep" "1")
17186    (set_attr "memory" "both")
17187    (set_attr "mode" "SI")])
17189 (define_expand "setmemsi"
17190    [(use (match_operand:BLK 0 "memory_operand" ""))
17191     (use (match_operand:SI 1 "nonmemory_operand" ""))
17192     (use (match_operand 2 "const_int_operand" ""))
17193     (use (match_operand 3 "const_int_operand" ""))]
17194   ""
17196  /* If value to set is not zero, use the library routine.  */
17197  if (operands[2] != const0_rtx)
17198    FAIL;
17200  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17201    DONE;
17202  else
17203    FAIL;
17206 (define_expand "setmemdi"
17207    [(use (match_operand:BLK 0 "memory_operand" ""))
17208     (use (match_operand:DI 1 "nonmemory_operand" ""))
17209     (use (match_operand 2 "const_int_operand" ""))
17210     (use (match_operand 3 "const_int_operand" ""))]
17211   "TARGET_64BIT"
17213  /* If value to set is not zero, use the library routine.  */
17214  if (operands[2] != const0_rtx)
17215    FAIL;
17217  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17218    DONE;
17219  else
17220    FAIL;
17223 ;; Most CPUs don't like single string operations
17224 ;; Handle this case here to simplify previous expander.
17226 (define_expand "strset"
17227   [(set (match_operand 1 "memory_operand" "")
17228         (match_operand 2 "register_operand" ""))
17229    (parallel [(set (match_operand 0 "register_operand" "")
17230                    (match_dup 3))
17231               (clobber (reg:CC FLAGS_REG))])]
17232   ""
17234   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17235     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17237   /* If .md ever supports :P for Pmode, this can be directly
17238      in the pattern above.  */
17239   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17240                               GEN_INT (GET_MODE_SIZE (GET_MODE
17241                                                       (operands[2]))));
17242   if (TARGET_SINGLE_STRINGOP || optimize_size)
17243     {
17244       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17245                                       operands[3]));
17246       DONE;
17247     }
17250 (define_expand "strset_singleop"
17251   [(parallel [(set (match_operand 1 "memory_operand" "")
17252                    (match_operand 2 "register_operand" ""))
17253               (set (match_operand 0 "register_operand" "")
17254                    (match_operand 3 "" ""))
17255               (use (reg:SI DIRFLAG_REG))])]
17256   "TARGET_SINGLE_STRINGOP || optimize_size"
17257   "")
17259 (define_insn "*strsetdi_rex_1"
17260   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17261         (match_operand:DI 2 "register_operand" "a"))
17262    (set (match_operand:DI 0 "register_operand" "=D")
17263         (plus:DI (match_dup 1)
17264                  (const_int 8)))
17265    (use (reg:SI DIRFLAG_REG))]
17266   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17267   "stosq"
17268   [(set_attr "type" "str")
17269    (set_attr "memory" "store")
17270    (set_attr "mode" "DI")])
17272 (define_insn "*strsetsi_1"
17273   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17274         (match_operand:SI 2 "register_operand" "a"))
17275    (set (match_operand:SI 0 "register_operand" "=D")
17276         (plus:SI (match_dup 1)
17277                  (const_int 4)))
17278    (use (reg:SI DIRFLAG_REG))]
17279   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17280   "{stosl|stosd}"
17281   [(set_attr "type" "str")
17282    (set_attr "memory" "store")
17283    (set_attr "mode" "SI")])
17285 (define_insn "*strsetsi_rex_1"
17286   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17287         (match_operand:SI 2 "register_operand" "a"))
17288    (set (match_operand:DI 0 "register_operand" "=D")
17289         (plus:DI (match_dup 1)
17290                  (const_int 4)))
17291    (use (reg:SI DIRFLAG_REG))]
17292   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17293   "{stosl|stosd}"
17294   [(set_attr "type" "str")
17295    (set_attr "memory" "store")
17296    (set_attr "mode" "SI")])
17298 (define_insn "*strsethi_1"
17299   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17300         (match_operand:HI 2 "register_operand" "a"))
17301    (set (match_operand:SI 0 "register_operand" "=D")
17302         (plus:SI (match_dup 1)
17303                  (const_int 2)))
17304    (use (reg:SI DIRFLAG_REG))]
17305   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17306   "stosw"
17307   [(set_attr "type" "str")
17308    (set_attr "memory" "store")
17309    (set_attr "mode" "HI")])
17311 (define_insn "*strsethi_rex_1"
17312   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17313         (match_operand:HI 2 "register_operand" "a"))
17314    (set (match_operand:DI 0 "register_operand" "=D")
17315         (plus:DI (match_dup 1)
17316                  (const_int 2)))
17317    (use (reg:SI DIRFLAG_REG))]
17318   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17319   "stosw"
17320   [(set_attr "type" "str")
17321    (set_attr "memory" "store")
17322    (set_attr "mode" "HI")])
17324 (define_insn "*strsetqi_1"
17325   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17326         (match_operand:QI 2 "register_operand" "a"))
17327    (set (match_operand:SI 0 "register_operand" "=D")
17328         (plus:SI (match_dup 1)
17329                  (const_int 1)))
17330    (use (reg:SI DIRFLAG_REG))]
17331   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17332   "stosb"
17333   [(set_attr "type" "str")
17334    (set_attr "memory" "store")
17335    (set_attr "mode" "QI")])
17337 (define_insn "*strsetqi_rex_1"
17338   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17339         (match_operand:QI 2 "register_operand" "a"))
17340    (set (match_operand:DI 0 "register_operand" "=D")
17341         (plus:DI (match_dup 1)
17342                  (const_int 1)))
17343    (use (reg:SI DIRFLAG_REG))]
17344   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17345   "stosb"
17346   [(set_attr "type" "str")
17347    (set_attr "memory" "store")
17348    (set_attr "mode" "QI")])
17350 (define_expand "rep_stos"
17351   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17352               (set (match_operand 0 "register_operand" "")
17353                    (match_operand 4 "" ""))
17354               (set (match_operand 2 "memory_operand" "") (const_int 0))
17355               (use (match_operand 3 "register_operand" ""))
17356               (use (match_dup 1))
17357               (use (reg:SI DIRFLAG_REG))])]
17358   ""
17359   "")
17361 (define_insn "*rep_stosdi_rex64"
17362   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17363    (set (match_operand:DI 0 "register_operand" "=D") 
17364         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17365                             (const_int 3))
17366                  (match_operand:DI 3 "register_operand" "0")))
17367    (set (mem:BLK (match_dup 3))
17368         (const_int 0))
17369    (use (match_operand:DI 2 "register_operand" "a"))
17370    (use (match_dup 4))
17371    (use (reg:SI DIRFLAG_REG))]
17372   "TARGET_64BIT"
17373   "{rep\;stosq|rep stosq}"
17374   [(set_attr "type" "str")
17375    (set_attr "prefix_rep" "1")
17376    (set_attr "memory" "store")
17377    (set_attr "mode" "DI")])
17379 (define_insn "*rep_stossi"
17380   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17381    (set (match_operand:SI 0 "register_operand" "=D") 
17382         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17383                             (const_int 2))
17384                  (match_operand:SI 3 "register_operand" "0")))
17385    (set (mem:BLK (match_dup 3))
17386         (const_int 0))
17387    (use (match_operand:SI 2 "register_operand" "a"))
17388    (use (match_dup 4))
17389    (use (reg:SI DIRFLAG_REG))]
17390   "!TARGET_64BIT"
17391   "{rep\;stosl|rep stosd}"
17392   [(set_attr "type" "str")
17393    (set_attr "prefix_rep" "1")
17394    (set_attr "memory" "store")
17395    (set_attr "mode" "SI")])
17397 (define_insn "*rep_stossi_rex64"
17398   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17399    (set (match_operand:DI 0 "register_operand" "=D") 
17400         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17401                             (const_int 2))
17402                  (match_operand:DI 3 "register_operand" "0")))
17403    (set (mem:BLK (match_dup 3))
17404         (const_int 0))
17405    (use (match_operand:SI 2 "register_operand" "a"))
17406    (use (match_dup 4))
17407    (use (reg:SI DIRFLAG_REG))]
17408   "TARGET_64BIT"
17409   "{rep\;stosl|rep stosd}"
17410   [(set_attr "type" "str")
17411    (set_attr "prefix_rep" "1")
17412    (set_attr "memory" "store")
17413    (set_attr "mode" "SI")])
17415 (define_insn "*rep_stosqi"
17416   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17417    (set (match_operand:SI 0 "register_operand" "=D") 
17418         (plus:SI (match_operand:SI 3 "register_operand" "0")
17419                  (match_operand:SI 4 "register_operand" "1")))
17420    (set (mem:BLK (match_dup 3))
17421         (const_int 0))
17422    (use (match_operand:QI 2 "register_operand" "a"))
17423    (use (match_dup 4))
17424    (use (reg:SI DIRFLAG_REG))]
17425   "!TARGET_64BIT"
17426   "{rep\;stosb|rep stosb}"
17427   [(set_attr "type" "str")
17428    (set_attr "prefix_rep" "1")
17429    (set_attr "memory" "store")
17430    (set_attr "mode" "QI")])
17432 (define_insn "*rep_stosqi_rex64"
17433   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17434    (set (match_operand:DI 0 "register_operand" "=D") 
17435         (plus:DI (match_operand:DI 3 "register_operand" "0")
17436                  (match_operand:DI 4 "register_operand" "1")))
17437    (set (mem:BLK (match_dup 3))
17438         (const_int 0))
17439    (use (match_operand:QI 2 "register_operand" "a"))
17440    (use (match_dup 4))
17441    (use (reg:SI DIRFLAG_REG))]
17442   "TARGET_64BIT"
17443   "{rep\;stosb|rep stosb}"
17444   [(set_attr "type" "str")
17445    (set_attr "prefix_rep" "1")
17446    (set_attr "memory" "store")
17447    (set_attr "mode" "QI")])
17449 (define_expand "cmpstrsi"
17450   [(set (match_operand:SI 0 "register_operand" "")
17451         (compare:SI (match_operand:BLK 1 "general_operand" "")
17452                     (match_operand:BLK 2 "general_operand" "")))
17453    (use (match_operand 3 "general_operand" ""))
17454    (use (match_operand 4 "immediate_operand" ""))]
17455   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17457   rtx addr1, addr2, out, outlow, count, countreg, align;
17459   /* Can't use this if the user has appropriated esi or edi.  */
17460   if (global_regs[4] || global_regs[5])
17461     FAIL;
17463   out = operands[0];
17464   if (GET_CODE (out) != REG)
17465     out = gen_reg_rtx (SImode);
17467   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17468   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17469   if (addr1 != XEXP (operands[1], 0))
17470     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17471   if (addr2 != XEXP (operands[2], 0))
17472     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17474   count = operands[3];
17475   countreg = ix86_zero_extend_to_Pmode (count);
17477   /* %%% Iff we are testing strict equality, we can use known alignment
17478      to good advantage.  This may be possible with combine, particularly
17479      once cc0 is dead.  */
17480   align = operands[4];
17482   emit_insn (gen_cld ());
17483   if (GET_CODE (count) == CONST_INT)
17484     {
17485       if (INTVAL (count) == 0)
17486         {
17487           emit_move_insn (operands[0], const0_rtx);
17488           DONE;
17489         }
17490       emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17491                                     operands[1], operands[2]));
17492     }
17493   else
17494     {
17495       if (TARGET_64BIT)
17496         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17497       else
17498         emit_insn (gen_cmpsi_1 (countreg, countreg));
17499       emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17500                                  operands[1], operands[2]));
17501     }
17503   outlow = gen_lowpart (QImode, out);
17504   emit_insn (gen_cmpintqi (outlow));
17505   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17507   if (operands[0] != out)
17508     emit_move_insn (operands[0], out);
17510   DONE;
17513 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17515 (define_expand "cmpintqi"
17516   [(set (match_dup 1)
17517         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17518    (set (match_dup 2)
17519         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17520    (parallel [(set (match_operand:QI 0 "register_operand" "")
17521                    (minus:QI (match_dup 1)
17522                              (match_dup 2)))
17523               (clobber (reg:CC FLAGS_REG))])]
17524   ""
17525   "operands[1] = gen_reg_rtx (QImode);
17526    operands[2] = gen_reg_rtx (QImode);")
17528 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17529 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17531 (define_expand "cmpstrqi_nz_1"
17532   [(parallel [(set (reg:CC FLAGS_REG)
17533                    (compare:CC (match_operand 4 "memory_operand" "")
17534                                (match_operand 5 "memory_operand" "")))
17535               (use (match_operand 2 "register_operand" ""))
17536               (use (match_operand:SI 3 "immediate_operand" ""))
17537               (use (reg:SI DIRFLAG_REG))
17538               (clobber (match_operand 0 "register_operand" ""))
17539               (clobber (match_operand 1 "register_operand" ""))
17540               (clobber (match_dup 2))])]
17541   ""
17542   "")
17544 (define_insn "*cmpstrqi_nz_1"
17545   [(set (reg:CC FLAGS_REG)
17546         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17547                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17548    (use (match_operand:SI 6 "register_operand" "2"))
17549    (use (match_operand:SI 3 "immediate_operand" "i"))
17550    (use (reg:SI DIRFLAG_REG))
17551    (clobber (match_operand:SI 0 "register_operand" "=S"))
17552    (clobber (match_operand:SI 1 "register_operand" "=D"))
17553    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17554   "!TARGET_64BIT"
17555   "repz{\;| }cmpsb"
17556   [(set_attr "type" "str")
17557    (set_attr "mode" "QI")
17558    (set_attr "prefix_rep" "1")])
17560 (define_insn "*cmpstrqi_nz_rex_1"
17561   [(set (reg:CC FLAGS_REG)
17562         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17563                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17564    (use (match_operand:DI 6 "register_operand" "2"))
17565    (use (match_operand:SI 3 "immediate_operand" "i"))
17566    (use (reg:SI DIRFLAG_REG))
17567    (clobber (match_operand:DI 0 "register_operand" "=S"))
17568    (clobber (match_operand:DI 1 "register_operand" "=D"))
17569    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17570   "TARGET_64BIT"
17571   "repz{\;| }cmpsb"
17572   [(set_attr "type" "str")
17573    (set_attr "mode" "QI")
17574    (set_attr "prefix_rep" "1")])
17576 ;; The same, but the count is not known to not be zero.
17578 (define_expand "cmpstrqi_1"
17579   [(parallel [(set (reg:CC FLAGS_REG)
17580                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17581                                      (const_int 0))
17582                   (compare:CC (match_operand 4 "memory_operand" "")
17583                               (match_operand 5 "memory_operand" ""))
17584                   (const_int 0)))
17585               (use (match_operand:SI 3 "immediate_operand" ""))
17586               (use (reg:CC FLAGS_REG))
17587               (use (reg:SI DIRFLAG_REG))
17588               (clobber (match_operand 0 "register_operand" ""))
17589               (clobber (match_operand 1 "register_operand" ""))
17590               (clobber (match_dup 2))])]
17591   ""
17592   "")
17594 (define_insn "*cmpstrqi_1"
17595   [(set (reg:CC FLAGS_REG)
17596         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17597                              (const_int 0))
17598           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17599                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17600           (const_int 0)))
17601    (use (match_operand:SI 3 "immediate_operand" "i"))
17602    (use (reg:CC FLAGS_REG))
17603    (use (reg:SI DIRFLAG_REG))
17604    (clobber (match_operand:SI 0 "register_operand" "=S"))
17605    (clobber (match_operand:SI 1 "register_operand" "=D"))
17606    (clobber (match_operand:SI 2 "register_operand" "=c"))]
17607   "!TARGET_64BIT"
17608   "repz{\;| }cmpsb"
17609   [(set_attr "type" "str")
17610    (set_attr "mode" "QI")
17611    (set_attr "prefix_rep" "1")])
17613 (define_insn "*cmpstrqi_rex_1"
17614   [(set (reg:CC FLAGS_REG)
17615         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17616                              (const_int 0))
17617           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17618                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17619           (const_int 0)))
17620    (use (match_operand:SI 3 "immediate_operand" "i"))
17621    (use (reg:CC FLAGS_REG))
17622    (use (reg:SI DIRFLAG_REG))
17623    (clobber (match_operand:DI 0 "register_operand" "=S"))
17624    (clobber (match_operand:DI 1 "register_operand" "=D"))
17625    (clobber (match_operand:DI 2 "register_operand" "=c"))]
17626   "TARGET_64BIT"
17627   "repz{\;| }cmpsb"
17628   [(set_attr "type" "str")
17629    (set_attr "mode" "QI")
17630    (set_attr "prefix_rep" "1")])
17632 (define_expand "strlensi"
17633   [(set (match_operand:SI 0 "register_operand" "")
17634         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17635                     (match_operand:QI 2 "immediate_operand" "")
17636                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17637   ""
17639  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17640    DONE;
17641  else
17642    FAIL;
17645 (define_expand "strlendi"
17646   [(set (match_operand:DI 0 "register_operand" "")
17647         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17648                     (match_operand:QI 2 "immediate_operand" "")
17649                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17650   ""
17652  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17653    DONE;
17654  else
17655    FAIL;
17658 (define_expand "strlenqi_1"
17659   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17660               (use (reg:SI DIRFLAG_REG))
17661               (clobber (match_operand 1 "register_operand" ""))
17662               (clobber (reg:CC FLAGS_REG))])]
17663   ""
17664   "")
17666 (define_insn "*strlenqi_1"
17667   [(set (match_operand:SI 0 "register_operand" "=&c")
17668         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17669                     (match_operand:QI 2 "register_operand" "a")
17670                     (match_operand:SI 3 "immediate_operand" "i")
17671                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17672    (use (reg:SI DIRFLAG_REG))
17673    (clobber (match_operand:SI 1 "register_operand" "=D"))
17674    (clobber (reg:CC FLAGS_REG))]
17675   "!TARGET_64BIT"
17676   "repnz{\;| }scasb"
17677   [(set_attr "type" "str")
17678    (set_attr "mode" "QI")
17679    (set_attr "prefix_rep" "1")])
17681 (define_insn "*strlenqi_rex_1"
17682   [(set (match_operand:DI 0 "register_operand" "=&c")
17683         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17684                     (match_operand:QI 2 "register_operand" "a")
17685                     (match_operand:DI 3 "immediate_operand" "i")
17686                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17687    (use (reg:SI DIRFLAG_REG))
17688    (clobber (match_operand:DI 1 "register_operand" "=D"))
17689    (clobber (reg:CC FLAGS_REG))]
17690   "TARGET_64BIT"
17691   "repnz{\;| }scasb"
17692   [(set_attr "type" "str")
17693    (set_attr "mode" "QI")
17694    (set_attr "prefix_rep" "1")])
17696 ;; Peephole optimizations to clean up after cmpstr*.  This should be
17697 ;; handled in combine, but it is not currently up to the task.
17698 ;; When used for their truth value, the cmpstr* expanders generate
17699 ;; code like this:
17701 ;;   repz cmpsb
17702 ;;   seta       %al
17703 ;;   setb       %dl
17704 ;;   cmpb       %al, %dl
17705 ;;   jcc        label
17707 ;; The intermediate three instructions are unnecessary.
17709 ;; This one handles cmpstr*_nz_1...
17710 (define_peephole2
17711   [(parallel[
17712      (set (reg:CC FLAGS_REG)
17713           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17714                       (mem:BLK (match_operand 5 "register_operand" ""))))
17715      (use (match_operand 6 "register_operand" ""))
17716      (use (match_operand:SI 3 "immediate_operand" ""))
17717      (use (reg:SI DIRFLAG_REG))
17718      (clobber (match_operand 0 "register_operand" ""))
17719      (clobber (match_operand 1 "register_operand" ""))
17720      (clobber (match_operand 2 "register_operand" ""))])
17721    (set (match_operand:QI 7 "register_operand" "")
17722         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17723    (set (match_operand:QI 8 "register_operand" "")
17724         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17725    (set (reg FLAGS_REG)
17726         (compare (match_dup 7) (match_dup 8)))
17727   ]
17728   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17729   [(parallel[
17730      (set (reg:CC FLAGS_REG)
17731           (compare:CC (mem:BLK (match_dup 4))
17732                       (mem:BLK (match_dup 5))))
17733      (use (match_dup 6))
17734      (use (match_dup 3))
17735      (use (reg:SI DIRFLAG_REG))
17736      (clobber (match_dup 0))
17737      (clobber (match_dup 1))
17738      (clobber (match_dup 2))])]
17739   "")
17741 ;; ...and this one handles cmpstr*_1.
17742 (define_peephole2
17743   [(parallel[
17744      (set (reg:CC FLAGS_REG)
17745           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17746                                (const_int 0))
17747             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17748                         (mem:BLK (match_operand 5 "register_operand" "")))
17749             (const_int 0)))
17750      (use (match_operand:SI 3 "immediate_operand" ""))
17751      (use (reg:CC FLAGS_REG))
17752      (use (reg:SI DIRFLAG_REG))
17753      (clobber (match_operand 0 "register_operand" ""))
17754      (clobber (match_operand 1 "register_operand" ""))
17755      (clobber (match_operand 2 "register_operand" ""))])
17756    (set (match_operand:QI 7 "register_operand" "")
17757         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17758    (set (match_operand:QI 8 "register_operand" "")
17759         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17760    (set (reg FLAGS_REG)
17761         (compare (match_dup 7) (match_dup 8)))
17762   ]
17763   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17764   [(parallel[
17765      (set (reg:CC FLAGS_REG)
17766           (if_then_else:CC (ne (match_dup 6)
17767                                (const_int 0))
17768             (compare:CC (mem:BLK (match_dup 4))
17769                         (mem:BLK (match_dup 5)))
17770             (const_int 0)))
17771      (use (match_dup 3))
17772      (use (reg:CC FLAGS_REG))
17773      (use (reg:SI DIRFLAG_REG))
17774      (clobber (match_dup 0))
17775      (clobber (match_dup 1))
17776      (clobber (match_dup 2))])]
17777   "")
17781 ;; Conditional move instructions.
17783 (define_expand "movdicc"
17784   [(set (match_operand:DI 0 "register_operand" "")
17785         (if_then_else:DI (match_operand 1 "comparison_operator" "")
17786                          (match_operand:DI 2 "general_operand" "")
17787                          (match_operand:DI 3 "general_operand" "")))]
17788   "TARGET_64BIT"
17789   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17791 (define_insn "x86_movdicc_0_m1_rex64"
17792   [(set (match_operand:DI 0 "register_operand" "=r")
17793         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17794           (const_int -1)
17795           (const_int 0)))
17796    (clobber (reg:CC FLAGS_REG))]
17797   "TARGET_64BIT"
17798   "sbb{q}\t%0, %0"
17799   ; Since we don't have the proper number of operands for an alu insn,
17800   ; fill in all the blanks.
17801   [(set_attr "type" "alu")
17802    (set_attr "pent_pair" "pu")
17803    (set_attr "memory" "none")
17804    (set_attr "imm_disp" "false")
17805    (set_attr "mode" "DI")
17806    (set_attr "length_immediate" "0")])
17808 (define_insn "*movdicc_c_rex64"
17809   [(set (match_operand:DI 0 "register_operand" "=r,r")
17810         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
17811                                 [(reg FLAGS_REG) (const_int 0)])
17812                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17813                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17814   "TARGET_64BIT && TARGET_CMOVE
17815    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17816   "@
17817    cmov%O2%C1\t{%2, %0|%0, %2}
17818    cmov%O2%c1\t{%3, %0|%0, %3}"
17819   [(set_attr "type" "icmov")
17820    (set_attr "mode" "DI")])
17822 (define_expand "movsicc"
17823   [(set (match_operand:SI 0 "register_operand" "")
17824         (if_then_else:SI (match_operand 1 "comparison_operator" "")
17825                          (match_operand:SI 2 "general_operand" "")
17826                          (match_operand:SI 3 "general_operand" "")))]
17827   ""
17828   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17830 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17831 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17832 ;; So just document what we're doing explicitly.
17834 (define_insn "x86_movsicc_0_m1"
17835   [(set (match_operand:SI 0 "register_operand" "=r")
17836         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17837           (const_int -1)
17838           (const_int 0)))
17839    (clobber (reg:CC FLAGS_REG))]
17840   ""
17841   "sbb{l}\t%0, %0"
17842   ; Since we don't have the proper number of operands for an alu insn,
17843   ; fill in all the blanks.
17844   [(set_attr "type" "alu")
17845    (set_attr "pent_pair" "pu")
17846    (set_attr "memory" "none")
17847    (set_attr "imm_disp" "false")
17848    (set_attr "mode" "SI")
17849    (set_attr "length_immediate" "0")])
17851 (define_insn "*movsicc_noc"
17852   [(set (match_operand:SI 0 "register_operand" "=r,r")
17853         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
17854                                 [(reg FLAGS_REG) (const_int 0)])
17855                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17856                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17857   "TARGET_CMOVE
17858    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17859   "@
17860    cmov%O2%C1\t{%2, %0|%0, %2}
17861    cmov%O2%c1\t{%3, %0|%0, %3}"
17862   [(set_attr "type" "icmov")
17863    (set_attr "mode" "SI")])
17865 (define_expand "movhicc"
17866   [(set (match_operand:HI 0 "register_operand" "")
17867         (if_then_else:HI (match_operand 1 "comparison_operator" "")
17868                          (match_operand:HI 2 "general_operand" "")
17869                          (match_operand:HI 3 "general_operand" "")))]
17870   "TARGET_HIMODE_MATH"
17871   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17873 (define_insn "*movhicc_noc"
17874   [(set (match_operand:HI 0 "register_operand" "=r,r")
17875         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
17876                                 [(reg FLAGS_REG) (const_int 0)])
17877                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17878                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17879   "TARGET_CMOVE
17880    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17881   "@
17882    cmov%O2%C1\t{%2, %0|%0, %2}
17883    cmov%O2%c1\t{%3, %0|%0, %3}"
17884   [(set_attr "type" "icmov")
17885    (set_attr "mode" "HI")])
17887 (define_expand "movqicc"
17888   [(set (match_operand:QI 0 "register_operand" "")
17889         (if_then_else:QI (match_operand 1 "comparison_operator" "")
17890                          (match_operand:QI 2 "general_operand" "")
17891                          (match_operand:QI 3 "general_operand" "")))]
17892   "TARGET_QIMODE_MATH"
17893   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17895 (define_insn_and_split "*movqicc_noc"
17896   [(set (match_operand:QI 0 "register_operand" "=r,r")
17897         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
17898                                 [(match_operand 4 "flags_reg_operand" "")
17899                                  (const_int 0)])
17900                       (match_operand:QI 2 "register_operand" "r,0")
17901                       (match_operand:QI 3 "register_operand" "0,r")))]
17902   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17903   "#"
17904   "&& reload_completed"
17905   [(set (match_dup 0)
17906         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17907                       (match_dup 2)
17908                       (match_dup 3)))]
17909   "operands[0] = gen_lowpart (SImode, operands[0]);
17910    operands[2] = gen_lowpart (SImode, operands[2]);
17911    operands[3] = gen_lowpart (SImode, operands[3]);"
17912   [(set_attr "type" "icmov")
17913    (set_attr "mode" "SI")])
17915 (define_expand "movsfcc"
17916   [(set (match_operand:SF 0 "register_operand" "")
17917         (if_then_else:SF (match_operand 1 "comparison_operator" "")
17918                          (match_operand:SF 2 "register_operand" "")
17919                          (match_operand:SF 3 "register_operand" "")))]
17920   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
17921   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17923 (define_insn "*movsfcc_1_387"
17924   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17925         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
17926                                 [(reg FLAGS_REG) (const_int 0)])
17927                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17928                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17929   "TARGET_80387 && TARGET_CMOVE
17930    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17931   "@
17932    fcmov%F1\t{%2, %0|%0, %2}
17933    fcmov%f1\t{%3, %0|%0, %3}
17934    cmov%O2%C1\t{%2, %0|%0, %2}
17935    cmov%O2%c1\t{%3, %0|%0, %3}"
17936   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17937    (set_attr "mode" "SF,SF,SI,SI")])
17939 (define_expand "movdfcc"
17940   [(set (match_operand:DF 0 "register_operand" "")
17941         (if_then_else:DF (match_operand 1 "comparison_operator" "")
17942                          (match_operand:DF 2 "register_operand" "")
17943                          (match_operand:DF 3 "register_operand" "")))]
17944   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
17945   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17947 (define_insn "*movdfcc_1"
17948   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17949         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17950                                 [(reg FLAGS_REG) (const_int 0)])
17951                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17952                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17953   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17954    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17955   "@
17956    fcmov%F1\t{%2, %0|%0, %2}
17957    fcmov%f1\t{%3, %0|%0, %3}
17958    #
17959    #"
17960   [(set_attr "type" "fcmov,fcmov,multi,multi")
17961    (set_attr "mode" "DF")])
17963 (define_insn "*movdfcc_1_rex64"
17964   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17965         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17966                                 [(reg FLAGS_REG) (const_int 0)])
17967                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17968                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17969   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17970    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17971   "@
17972    fcmov%F1\t{%2, %0|%0, %2}
17973    fcmov%f1\t{%3, %0|%0, %3}
17974    cmov%O2%C1\t{%2, %0|%0, %2}
17975    cmov%O2%c1\t{%3, %0|%0, %3}"
17976   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17977    (set_attr "mode" "DF")])
17979 (define_split
17980   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17981         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
17982                                 [(match_operand 4 "flags_reg_operand" "")
17983                                  (const_int 0)])
17984                       (match_operand:DF 2 "nonimmediate_operand" "")
17985                       (match_operand:DF 3 "nonimmediate_operand" "")))]
17986   "!TARGET_64BIT && reload_completed"
17987   [(set (match_dup 2)
17988         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17989                       (match_dup 5)
17990                       (match_dup 7)))
17991    (set (match_dup 3)
17992         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17993                       (match_dup 6)
17994                       (match_dup 8)))]
17995   "split_di (operands+2, 1, operands+5, operands+6);
17996    split_di (operands+3, 1, operands+7, operands+8);
17997    split_di (operands, 1, operands+2, operands+3);")
17999 (define_expand "movxfcc"
18000   [(set (match_operand:XF 0 "register_operand" "")
18001         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18002                          (match_operand:XF 2 "register_operand" "")
18003                          (match_operand:XF 3 "register_operand" "")))]
18004   "TARGET_80387 && TARGET_CMOVE"
18005   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18007 (define_insn "*movxfcc_1"
18008   [(set (match_operand:XF 0 "register_operand" "=f,f")
18009         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18010                                 [(reg FLAGS_REG) (const_int 0)])
18011                       (match_operand:XF 2 "register_operand" "f,0")
18012                       (match_operand:XF 3 "register_operand" "0,f")))]
18013   "TARGET_80387 && TARGET_CMOVE"
18014   "@
18015    fcmov%F1\t{%2, %0|%0, %2}
18016    fcmov%f1\t{%3, %0|%0, %3}"
18017   [(set_attr "type" "fcmov")
18018    (set_attr "mode" "XF")])
18020 ;; These versions of the min/max patterns are intentionally ignorant of
18021 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18022 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18023 ;; are undefined in this condition, we're certain this is correct.
18025 (define_insn "sminsf3"
18026   [(set (match_operand:SF 0 "register_operand" "=x")
18027         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18028                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18029   "TARGET_SSE_MATH"
18030   "minss\t{%2, %0|%0, %2}"
18031   [(set_attr "type" "sseadd")
18032    (set_attr "mode" "SF")])
18034 (define_insn "smaxsf3"
18035   [(set (match_operand:SF 0 "register_operand" "=x")
18036         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18037                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18038   "TARGET_SSE_MATH"
18039   "maxss\t{%2, %0|%0, %2}"
18040   [(set_attr "type" "sseadd")
18041    (set_attr "mode" "SF")])
18043 (define_insn "smindf3"
18044   [(set (match_operand:DF 0 "register_operand" "=x")
18045         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18046                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18047   "TARGET_SSE2 && TARGET_SSE_MATH"
18048   "minsd\t{%2, %0|%0, %2}"
18049   [(set_attr "type" "sseadd")
18050    (set_attr "mode" "DF")])
18052 (define_insn "smaxdf3"
18053   [(set (match_operand:DF 0 "register_operand" "=x")
18054         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18055                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18056   "TARGET_SSE2 && TARGET_SSE_MATH"
18057   "maxsd\t{%2, %0|%0, %2}"
18058   [(set_attr "type" "sseadd")
18059    (set_attr "mode" "DF")])
18061 ;; These versions of the min/max patterns implement exactly the operations
18062 ;;   min = (op1 < op2 ? op1 : op2)
18063 ;;   max = (!(op1 < op2) ? op1 : op2)
18064 ;; Their operands are not commutative, and thus they may be used in the
18065 ;; presence of -0.0 and NaN.
18067 (define_insn "*ieee_sminsf3"
18068   [(set (match_operand:SF 0 "register_operand" "=x")
18069         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18070                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18071                    UNSPEC_IEEE_MIN))]
18072   "TARGET_SSE_MATH"
18073   "minss\t{%2, %0|%0, %2}"
18074   [(set_attr "type" "sseadd")
18075    (set_attr "mode" "SF")])
18077 (define_insn "*ieee_smaxsf3"
18078   [(set (match_operand:SF 0 "register_operand" "=x")
18079         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18080                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18081                    UNSPEC_IEEE_MAX))]
18082   "TARGET_SSE_MATH"
18083   "maxss\t{%2, %0|%0, %2}"
18084   [(set_attr "type" "sseadd")
18085    (set_attr "mode" "SF")])
18087 (define_insn "*ieee_smindf3"
18088   [(set (match_operand:DF 0 "register_operand" "=x")
18089         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18090                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18091                    UNSPEC_IEEE_MIN))]
18092   "TARGET_SSE2 && TARGET_SSE_MATH"
18093   "minsd\t{%2, %0|%0, %2}"
18094   [(set_attr "type" "sseadd")
18095    (set_attr "mode" "DF")])
18097 (define_insn "*ieee_smaxdf3"
18098   [(set (match_operand:DF 0 "register_operand" "=x")
18099         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18100                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18101                    UNSPEC_IEEE_MAX))]
18102   "TARGET_SSE2 && TARGET_SSE_MATH"
18103   "maxsd\t{%2, %0|%0, %2}"
18104   [(set_attr "type" "sseadd")
18105    (set_attr "mode" "DF")])
18107 ;; Conditional addition patterns
18108 (define_expand "addqicc"
18109   [(match_operand:QI 0 "register_operand" "")
18110    (match_operand 1 "comparison_operator" "")
18111    (match_operand:QI 2 "register_operand" "")
18112    (match_operand:QI 3 "const_int_operand" "")]
18113   ""
18114   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18116 (define_expand "addhicc"
18117   [(match_operand:HI 0 "register_operand" "")
18118    (match_operand 1 "comparison_operator" "")
18119    (match_operand:HI 2 "register_operand" "")
18120    (match_operand:HI 3 "const_int_operand" "")]
18121   ""
18122   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18124 (define_expand "addsicc"
18125   [(match_operand:SI 0 "register_operand" "")
18126    (match_operand 1 "comparison_operator" "")
18127    (match_operand:SI 2 "register_operand" "")
18128    (match_operand:SI 3 "const_int_operand" "")]
18129   ""
18130   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18132 (define_expand "adddicc"
18133   [(match_operand:DI 0 "register_operand" "")
18134    (match_operand 1 "comparison_operator" "")
18135    (match_operand:DI 2 "register_operand" "")
18136    (match_operand:DI 3 "const_int_operand" "")]
18137   "TARGET_64BIT"
18138   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18141 ;; Misc patterns (?)
18143 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18144 ;; Otherwise there will be nothing to keep
18145 ;; 
18146 ;; [(set (reg ebp) (reg esp))]
18147 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18148 ;;  (clobber (eflags)]
18149 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18151 ;; in proper program order.
18152 (define_insn "pro_epilogue_adjust_stack_1"
18153   [(set (match_operand:SI 0 "register_operand" "=r,r")
18154         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18155                  (match_operand:SI 2 "immediate_operand" "i,i")))
18156    (clobber (reg:CC FLAGS_REG))
18157    (clobber (mem:BLK (scratch)))]
18158   "!TARGET_64BIT"
18160   switch (get_attr_type (insn))
18161     {
18162     case TYPE_IMOV:
18163       return "mov{l}\t{%1, %0|%0, %1}";
18165     case TYPE_ALU:
18166       if (GET_CODE (operands[2]) == CONST_INT
18167           && (INTVAL (operands[2]) == 128
18168               || (INTVAL (operands[2]) < 0
18169                   && INTVAL (operands[2]) != -128)))
18170         {
18171           operands[2] = GEN_INT (-INTVAL (operands[2]));
18172           return "sub{l}\t{%2, %0|%0, %2}";
18173         }
18174       return "add{l}\t{%2, %0|%0, %2}";
18176     case TYPE_LEA:
18177       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18178       return "lea{l}\t{%a2, %0|%0, %a2}";
18180     default:
18181       gcc_unreachable ();
18182     }
18184   [(set (attr "type")
18185         (cond [(eq_attr "alternative" "0")
18186                  (const_string "alu")
18187                (match_operand:SI 2 "const0_operand" "")
18188                  (const_string "imov")
18189               ]
18190               (const_string "lea")))
18191    (set_attr "mode" "SI")])
18193 (define_insn "pro_epilogue_adjust_stack_rex64"
18194   [(set (match_operand:DI 0 "register_operand" "=r,r")
18195         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18196                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18197    (clobber (reg:CC FLAGS_REG))
18198    (clobber (mem:BLK (scratch)))]
18199   "TARGET_64BIT"
18201   switch (get_attr_type (insn))
18202     {
18203     case TYPE_IMOV:
18204       return "mov{q}\t{%1, %0|%0, %1}";
18206     case TYPE_ALU:
18207       if (GET_CODE (operands[2]) == CONST_INT
18208           /* Avoid overflows.  */
18209           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18210           && (INTVAL (operands[2]) == 128
18211               || (INTVAL (operands[2]) < 0
18212                   && INTVAL (operands[2]) != -128)))
18213         {
18214           operands[2] = GEN_INT (-INTVAL (operands[2]));
18215           return "sub{q}\t{%2, %0|%0, %2}";
18216         }
18217       return "add{q}\t{%2, %0|%0, %2}";
18219     case TYPE_LEA:
18220       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18221       return "lea{q}\t{%a2, %0|%0, %a2}";
18223     default:
18224       gcc_unreachable ();
18225     }
18227   [(set (attr "type")
18228         (cond [(eq_attr "alternative" "0")
18229                  (const_string "alu")
18230                (match_operand:DI 2 "const0_operand" "")
18231                  (const_string "imov")
18232               ]
18233               (const_string "lea")))
18234    (set_attr "mode" "DI")])
18236 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18237   [(set (match_operand:DI 0 "register_operand" "=r,r")
18238         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18239                  (match_operand:DI 3 "immediate_operand" "i,i")))
18240    (use (match_operand:DI 2 "register_operand" "r,r"))
18241    (clobber (reg:CC FLAGS_REG))
18242    (clobber (mem:BLK (scratch)))]
18243   "TARGET_64BIT"
18245   switch (get_attr_type (insn))
18246     {
18247     case TYPE_ALU:
18248       return "add{q}\t{%2, %0|%0, %2}";
18250     case TYPE_LEA:
18251       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18252       return "lea{q}\t{%a2, %0|%0, %a2}";
18254     default:
18255       gcc_unreachable ();
18256     }
18258   [(set_attr "type" "alu,lea")
18259    (set_attr "mode" "DI")])
18261 (define_expand "allocate_stack_worker"
18262   [(match_operand:SI 0 "register_operand" "")]
18263   "TARGET_STACK_PROBE"
18265   if (reload_completed)
18266     {
18267       if (TARGET_64BIT)
18268         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18269       else
18270         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18271     }
18272   else
18273     {
18274       if (TARGET_64BIT)
18275         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18276       else
18277         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18278     }
18279   DONE;
18282 (define_insn "allocate_stack_worker_1"
18283   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18284     UNSPECV_STACK_PROBE)
18285    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18286    (clobber (match_scratch:SI 1 "=0"))
18287    (clobber (reg:CC FLAGS_REG))]
18288   "!TARGET_64BIT && TARGET_STACK_PROBE"
18289   "call\t__alloca"
18290   [(set_attr "type" "multi")
18291    (set_attr "length" "5")])
18293 (define_expand "allocate_stack_worker_postreload"
18294   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18295                                     UNSPECV_STACK_PROBE)
18296               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18297               (clobber (match_dup 0))
18298               (clobber (reg:CC FLAGS_REG))])]
18299   ""
18300   "")
18302 (define_insn "allocate_stack_worker_rex64"
18303   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18304     UNSPECV_STACK_PROBE)
18305    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18306    (clobber (match_scratch:DI 1 "=0"))
18307    (clobber (reg:CC FLAGS_REG))]
18308   "TARGET_64BIT && TARGET_STACK_PROBE"
18309   "call\t__alloca"
18310   [(set_attr "type" "multi")
18311    (set_attr "length" "5")])
18313 (define_expand "allocate_stack_worker_rex64_postreload"
18314   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18315                                     UNSPECV_STACK_PROBE)
18316               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18317               (clobber (match_dup 0))
18318               (clobber (reg:CC FLAGS_REG))])]
18319   ""
18320   "")
18322 (define_expand "allocate_stack"
18323   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18324                    (minus:SI (reg:SI SP_REG)
18325                              (match_operand:SI 1 "general_operand" "")))
18326               (clobber (reg:CC FLAGS_REG))])
18327    (parallel [(set (reg:SI SP_REG)
18328                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18329               (clobber (reg:CC FLAGS_REG))])]
18330   "TARGET_STACK_PROBE"
18332 #ifdef CHECK_STACK_LIMIT
18333   if (GET_CODE (operands[1]) == CONST_INT
18334       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18335     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18336                            operands[1]));
18337   else 
18338 #endif
18339     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18340                                                             operands[1])));
18342   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18343   DONE;
18346 (define_expand "builtin_setjmp_receiver"
18347   [(label_ref (match_operand 0 "" ""))]
18348   "!TARGET_64BIT && flag_pic"
18350   emit_insn (gen_set_got (pic_offset_table_rtx));
18351   DONE;
18354 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18356 (define_split
18357   [(set (match_operand 0 "register_operand" "")
18358         (match_operator 3 "promotable_binary_operator"
18359            [(match_operand 1 "register_operand" "")
18360             (match_operand 2 "aligned_operand" "")]))
18361    (clobber (reg:CC FLAGS_REG))]
18362   "! TARGET_PARTIAL_REG_STALL && reload_completed
18363    && ((GET_MODE (operands[0]) == HImode 
18364         && ((!optimize_size && !TARGET_FAST_PREFIX)
18365             || GET_CODE (operands[2]) != CONST_INT
18366             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18367        || (GET_MODE (operands[0]) == QImode 
18368            && (TARGET_PROMOTE_QImode || optimize_size)))"
18369   [(parallel [(set (match_dup 0)
18370                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18371               (clobber (reg:CC FLAGS_REG))])]
18372   "operands[0] = gen_lowpart (SImode, operands[0]);
18373    operands[1] = gen_lowpart (SImode, operands[1]);
18374    if (GET_CODE (operands[3]) != ASHIFT)
18375      operands[2] = gen_lowpart (SImode, operands[2]);
18376    PUT_MODE (operands[3], SImode);")
18378 ; Promote the QImode tests, as i386 has encoding of the AND
18379 ; instruction with 32-bit sign-extended immediate and thus the
18380 ; instruction size is unchanged, except in the %eax case for
18381 ; which it is increased by one byte, hence the ! optimize_size.
18382 (define_split
18383   [(set (match_operand 0 "flags_reg_operand" "")
18384         (match_operator 2 "compare_operator"
18385           [(and (match_operand 3 "aligned_operand" "")
18386                 (match_operand 4 "const_int_operand" ""))
18387            (const_int 0)]))
18388    (set (match_operand 1 "register_operand" "")
18389         (and (match_dup 3) (match_dup 4)))]
18390   "! TARGET_PARTIAL_REG_STALL && reload_completed
18391    /* Ensure that the operand will remain sign-extended immediate.  */
18392    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18393    && ! optimize_size
18394    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18395        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18396   [(parallel [(set (match_dup 0)
18397                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18398                                     (const_int 0)]))
18399               (set (match_dup 1)
18400                    (and:SI (match_dup 3) (match_dup 4)))])]
18402   operands[4]
18403     = gen_int_mode (INTVAL (operands[4])
18404                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18405   operands[1] = gen_lowpart (SImode, operands[1]);
18406   operands[3] = gen_lowpart (SImode, operands[3]);
18409 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18410 ; the TEST instruction with 32-bit sign-extended immediate and thus
18411 ; the instruction size would at least double, which is not what we
18412 ; want even with ! optimize_size.
18413 (define_split
18414   [(set (match_operand 0 "flags_reg_operand" "")
18415         (match_operator 1 "compare_operator"
18416           [(and (match_operand:HI 2 "aligned_operand" "")
18417                 (match_operand:HI 3 "const_int_operand" ""))
18418            (const_int 0)]))]
18419   "! TARGET_PARTIAL_REG_STALL && reload_completed
18420    /* Ensure that the operand will remain sign-extended immediate.  */
18421    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18422    && ! TARGET_FAST_PREFIX
18423    && ! optimize_size"
18424   [(set (match_dup 0)
18425         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18426                          (const_int 0)]))]
18428   operands[3]
18429     = gen_int_mode (INTVAL (operands[3])
18430                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18431   operands[2] = gen_lowpart (SImode, operands[2]);
18434 (define_split
18435   [(set (match_operand 0 "register_operand" "")
18436         (neg (match_operand 1 "register_operand" "")))
18437    (clobber (reg:CC FLAGS_REG))]
18438   "! TARGET_PARTIAL_REG_STALL && reload_completed
18439    && (GET_MODE (operands[0]) == HImode
18440        || (GET_MODE (operands[0]) == QImode 
18441            && (TARGET_PROMOTE_QImode || optimize_size)))"
18442   [(parallel [(set (match_dup 0)
18443                    (neg:SI (match_dup 1)))
18444               (clobber (reg:CC FLAGS_REG))])]
18445   "operands[0] = gen_lowpart (SImode, operands[0]);
18446    operands[1] = gen_lowpart (SImode, operands[1]);")
18448 (define_split
18449   [(set (match_operand 0 "register_operand" "")
18450         (not (match_operand 1 "register_operand" "")))]
18451   "! TARGET_PARTIAL_REG_STALL && reload_completed
18452    && (GET_MODE (operands[0]) == HImode
18453        || (GET_MODE (operands[0]) == QImode 
18454            && (TARGET_PROMOTE_QImode || optimize_size)))"
18455   [(set (match_dup 0)
18456         (not:SI (match_dup 1)))]
18457   "operands[0] = gen_lowpart (SImode, operands[0]);
18458    operands[1] = gen_lowpart (SImode, operands[1]);")
18460 (define_split 
18461   [(set (match_operand 0 "register_operand" "")
18462         (if_then_else (match_operator 1 "comparison_operator" 
18463                                 [(reg FLAGS_REG) (const_int 0)])
18464                       (match_operand 2 "register_operand" "")
18465                       (match_operand 3 "register_operand" "")))]
18466   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18467    && (GET_MODE (operands[0]) == HImode
18468        || (GET_MODE (operands[0]) == QImode 
18469            && (TARGET_PROMOTE_QImode || optimize_size)))"
18470   [(set (match_dup 0)
18471         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18472   "operands[0] = gen_lowpart (SImode, operands[0]);
18473    operands[2] = gen_lowpart (SImode, operands[2]);
18474    operands[3] = gen_lowpart (SImode, operands[3]);")
18475                         
18477 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18478 ;; transform a complex memory operation into two memory to register operations.
18480 ;; Don't push memory operands
18481 (define_peephole2
18482   [(set (match_operand:SI 0 "push_operand" "")
18483         (match_operand:SI 1 "memory_operand" ""))
18484    (match_scratch:SI 2 "r")]
18485   "! optimize_size && ! TARGET_PUSH_MEMORY"
18486   [(set (match_dup 2) (match_dup 1))
18487    (set (match_dup 0) (match_dup 2))]
18488   "")
18490 (define_peephole2
18491   [(set (match_operand:DI 0 "push_operand" "")
18492         (match_operand:DI 1 "memory_operand" ""))
18493    (match_scratch:DI 2 "r")]
18494   "! optimize_size && ! TARGET_PUSH_MEMORY"
18495   [(set (match_dup 2) (match_dup 1))
18496    (set (match_dup 0) (match_dup 2))]
18497   "")
18499 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18500 ;; SImode pushes.
18501 (define_peephole2
18502   [(set (match_operand:SF 0 "push_operand" "")
18503         (match_operand:SF 1 "memory_operand" ""))
18504    (match_scratch:SF 2 "r")]
18505   "! optimize_size && ! TARGET_PUSH_MEMORY"
18506   [(set (match_dup 2) (match_dup 1))
18507    (set (match_dup 0) (match_dup 2))]
18508   "")
18510 (define_peephole2
18511   [(set (match_operand:HI 0 "push_operand" "")
18512         (match_operand:HI 1 "memory_operand" ""))
18513    (match_scratch:HI 2 "r")]
18514   "! optimize_size && ! TARGET_PUSH_MEMORY"
18515   [(set (match_dup 2) (match_dup 1))
18516    (set (match_dup 0) (match_dup 2))]
18517   "")
18519 (define_peephole2
18520   [(set (match_operand:QI 0 "push_operand" "")
18521         (match_operand:QI 1 "memory_operand" ""))
18522    (match_scratch:QI 2 "q")]
18523   "! optimize_size && ! TARGET_PUSH_MEMORY"
18524   [(set (match_dup 2) (match_dup 1))
18525    (set (match_dup 0) (match_dup 2))]
18526   "")
18528 ;; Don't move an immediate directly to memory when the instruction
18529 ;; gets too big.
18530 (define_peephole2
18531   [(match_scratch:SI 1 "r")
18532    (set (match_operand:SI 0 "memory_operand" "")
18533         (const_int 0))]
18534   "! optimize_size
18535    && ! TARGET_USE_MOV0
18536    && TARGET_SPLIT_LONG_MOVES
18537    && get_attr_length (insn) >= ix86_cost->large_insn
18538    && peep2_regno_dead_p (0, FLAGS_REG)"
18539   [(parallel [(set (match_dup 1) (const_int 0))
18540               (clobber (reg:CC FLAGS_REG))])
18541    (set (match_dup 0) (match_dup 1))]
18542   "")
18544 (define_peephole2
18545   [(match_scratch:HI 1 "r")
18546    (set (match_operand:HI 0 "memory_operand" "")
18547         (const_int 0))]
18548   "! optimize_size
18549    && ! TARGET_USE_MOV0
18550    && TARGET_SPLIT_LONG_MOVES
18551    && get_attr_length (insn) >= ix86_cost->large_insn
18552    && peep2_regno_dead_p (0, FLAGS_REG)"
18553   [(parallel [(set (match_dup 2) (const_int 0))
18554               (clobber (reg:CC FLAGS_REG))])
18555    (set (match_dup 0) (match_dup 1))]
18556   "operands[2] = gen_lowpart (SImode, operands[1]);")
18558 (define_peephole2
18559   [(match_scratch:QI 1 "q")
18560    (set (match_operand:QI 0 "memory_operand" "")
18561         (const_int 0))]
18562   "! optimize_size
18563    && ! TARGET_USE_MOV0
18564    && TARGET_SPLIT_LONG_MOVES
18565    && get_attr_length (insn) >= ix86_cost->large_insn
18566    && peep2_regno_dead_p (0, FLAGS_REG)"
18567   [(parallel [(set (match_dup 2) (const_int 0))
18568               (clobber (reg:CC FLAGS_REG))])
18569    (set (match_dup 0) (match_dup 1))]
18570   "operands[2] = gen_lowpart (SImode, operands[1]);")
18572 (define_peephole2
18573   [(match_scratch:SI 2 "r")
18574    (set (match_operand:SI 0 "memory_operand" "")
18575         (match_operand:SI 1 "immediate_operand" ""))]
18576   "! optimize_size
18577    && get_attr_length (insn) >= ix86_cost->large_insn
18578    && TARGET_SPLIT_LONG_MOVES"
18579   [(set (match_dup 2) (match_dup 1))
18580    (set (match_dup 0) (match_dup 2))]
18581   "")
18583 (define_peephole2
18584   [(match_scratch:HI 2 "r")
18585    (set (match_operand:HI 0 "memory_operand" "")
18586         (match_operand:HI 1 "immediate_operand" ""))]
18587   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18588   && TARGET_SPLIT_LONG_MOVES"
18589   [(set (match_dup 2) (match_dup 1))
18590    (set (match_dup 0) (match_dup 2))]
18591   "")
18593 (define_peephole2
18594   [(match_scratch:QI 2 "q")
18595    (set (match_operand:QI 0 "memory_operand" "")
18596         (match_operand:QI 1 "immediate_operand" ""))]
18597   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18598   && TARGET_SPLIT_LONG_MOVES"
18599   [(set (match_dup 2) (match_dup 1))
18600    (set (match_dup 0) (match_dup 2))]
18601   "")
18603 ;; Don't compare memory with zero, load and use a test instead.
18604 (define_peephole2
18605   [(set (match_operand 0 "flags_reg_operand" "")
18606         (match_operator 1 "compare_operator"
18607           [(match_operand:SI 2 "memory_operand" "")
18608            (const_int 0)]))
18609    (match_scratch:SI 3 "r")]
18610   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18611   [(set (match_dup 3) (match_dup 2))
18612    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18613   "")
18615 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18616 ;; Don't split NOTs with a displacement operand, because resulting XOR
18617 ;; will not be pairable anyway.
18619 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18620 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18621 ;; so this split helps here as well.
18623 ;; Note: Can't do this as a regular split because we can't get proper
18624 ;; lifetime information then.
18626 (define_peephole2
18627   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18628         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18629   "!optimize_size
18630    && peep2_regno_dead_p (0, FLAGS_REG)
18631    && ((TARGET_PENTIUM 
18632         && (GET_CODE (operands[0]) != MEM
18633             || !memory_displacement_operand (operands[0], SImode)))
18634        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18635   [(parallel [(set (match_dup 0)
18636                    (xor:SI (match_dup 1) (const_int -1)))
18637               (clobber (reg:CC FLAGS_REG))])]
18638   "")
18640 (define_peephole2
18641   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18642         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18643   "!optimize_size
18644    && peep2_regno_dead_p (0, FLAGS_REG)
18645    && ((TARGET_PENTIUM 
18646         && (GET_CODE (operands[0]) != MEM
18647             || !memory_displacement_operand (operands[0], HImode)))
18648        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18649   [(parallel [(set (match_dup 0)
18650                    (xor:HI (match_dup 1) (const_int -1)))
18651               (clobber (reg:CC FLAGS_REG))])]
18652   "")
18654 (define_peephole2
18655   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18656         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18657   "!optimize_size
18658    && peep2_regno_dead_p (0, FLAGS_REG)
18659    && ((TARGET_PENTIUM 
18660         && (GET_CODE (operands[0]) != MEM
18661             || !memory_displacement_operand (operands[0], QImode)))
18662        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18663   [(parallel [(set (match_dup 0)
18664                    (xor:QI (match_dup 1) (const_int -1)))
18665               (clobber (reg:CC FLAGS_REG))])]
18666   "")
18668 ;; Non pairable "test imm, reg" instructions can be translated to
18669 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18670 ;; byte opcode instead of two, have a short form for byte operands),
18671 ;; so do it for other CPUs as well.  Given that the value was dead,
18672 ;; this should not create any new dependencies.  Pass on the sub-word
18673 ;; versions if we're concerned about partial register stalls.
18675 (define_peephole2
18676   [(set (match_operand 0 "flags_reg_operand" "")
18677         (match_operator 1 "compare_operator"
18678           [(and:SI (match_operand:SI 2 "register_operand" "")
18679                    (match_operand:SI 3 "immediate_operand" ""))
18680            (const_int 0)]))]
18681   "ix86_match_ccmode (insn, CCNOmode)
18682    && (true_regnum (operands[2]) != 0
18683        || (GET_CODE (operands[3]) == CONST_INT
18684            && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18685    && peep2_reg_dead_p (1, operands[2])"
18686   [(parallel
18687      [(set (match_dup 0)
18688            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18689                             (const_int 0)]))
18690       (set (match_dup 2)
18691            (and:SI (match_dup 2) (match_dup 3)))])]
18692   "")
18694 ;; We don't need to handle HImode case, because it will be promoted to SImode
18695 ;; on ! TARGET_PARTIAL_REG_STALL
18697 (define_peephole2
18698   [(set (match_operand 0 "flags_reg_operand" "")
18699         (match_operator 1 "compare_operator"
18700           [(and:QI (match_operand:QI 2 "register_operand" "")
18701                    (match_operand:QI 3 "immediate_operand" ""))
18702            (const_int 0)]))]
18703   "! TARGET_PARTIAL_REG_STALL
18704    && ix86_match_ccmode (insn, CCNOmode)
18705    && true_regnum (operands[2]) != 0
18706    && peep2_reg_dead_p (1, operands[2])"
18707   [(parallel
18708      [(set (match_dup 0)
18709            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18710                             (const_int 0)]))
18711       (set (match_dup 2)
18712            (and:QI (match_dup 2) (match_dup 3)))])]
18713   "")
18715 (define_peephole2
18716   [(set (match_operand 0 "flags_reg_operand" "")
18717         (match_operator 1 "compare_operator"
18718           [(and:SI
18719              (zero_extract:SI
18720                (match_operand 2 "ext_register_operand" "")
18721                (const_int 8)
18722                (const_int 8))
18723              (match_operand 3 "const_int_operand" ""))
18724            (const_int 0)]))]
18725   "! TARGET_PARTIAL_REG_STALL
18726    && ix86_match_ccmode (insn, CCNOmode)
18727    && true_regnum (operands[2]) != 0
18728    && peep2_reg_dead_p (1, operands[2])"
18729   [(parallel [(set (match_dup 0)
18730                    (match_op_dup 1
18731                      [(and:SI
18732                         (zero_extract:SI
18733                           (match_dup 2)
18734                           (const_int 8)
18735                           (const_int 8))
18736                         (match_dup 3))
18737                       (const_int 0)]))
18738               (set (zero_extract:SI (match_dup 2)
18739                                     (const_int 8)
18740                                     (const_int 8))
18741                    (and:SI 
18742                      (zero_extract:SI
18743                        (match_dup 2)
18744                        (const_int 8)
18745                        (const_int 8))
18746                      (match_dup 3)))])]
18747   "")
18749 ;; Don't do logical operations with memory inputs.
18750 (define_peephole2
18751   [(match_scratch:SI 2 "r")
18752    (parallel [(set (match_operand:SI 0 "register_operand" "")
18753                    (match_operator:SI 3 "arith_or_logical_operator"
18754                      [(match_dup 0)
18755                       (match_operand:SI 1 "memory_operand" "")]))
18756               (clobber (reg:CC FLAGS_REG))])]
18757   "! optimize_size && ! TARGET_READ_MODIFY"
18758   [(set (match_dup 2) (match_dup 1))
18759    (parallel [(set (match_dup 0)
18760                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18761               (clobber (reg:CC FLAGS_REG))])]
18762   "")
18764 (define_peephole2
18765   [(match_scratch:SI 2 "r")
18766    (parallel [(set (match_operand:SI 0 "register_operand" "")
18767                    (match_operator:SI 3 "arith_or_logical_operator"
18768                      [(match_operand:SI 1 "memory_operand" "")
18769                       (match_dup 0)]))
18770               (clobber (reg:CC FLAGS_REG))])]
18771   "! optimize_size && ! TARGET_READ_MODIFY"
18772   [(set (match_dup 2) (match_dup 1))
18773    (parallel [(set (match_dup 0)
18774                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18775               (clobber (reg:CC FLAGS_REG))])]
18776   "")
18778 ; Don't do logical operations with memory outputs
18780 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18781 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18782 ; the same decoder scheduling characteristics as the original.
18784 (define_peephole2
18785   [(match_scratch:SI 2 "r")
18786    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18787                    (match_operator:SI 3 "arith_or_logical_operator"
18788                      [(match_dup 0)
18789                       (match_operand:SI 1 "nonmemory_operand" "")]))
18790               (clobber (reg:CC FLAGS_REG))])]
18791   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18792   [(set (match_dup 2) (match_dup 0))
18793    (parallel [(set (match_dup 2)
18794                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18795               (clobber (reg:CC FLAGS_REG))])
18796    (set (match_dup 0) (match_dup 2))]
18797   "")
18799 (define_peephole2
18800   [(match_scratch:SI 2 "r")
18801    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18802                    (match_operator:SI 3 "arith_or_logical_operator"
18803                      [(match_operand:SI 1 "nonmemory_operand" "")
18804                       (match_dup 0)]))
18805               (clobber (reg:CC FLAGS_REG))])]
18806   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18807   [(set (match_dup 2) (match_dup 0))
18808    (parallel [(set (match_dup 2)
18809                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18810               (clobber (reg:CC FLAGS_REG))])
18811    (set (match_dup 0) (match_dup 2))]
18812   "")
18814 ;; Attempt to always use XOR for zeroing registers.
18815 (define_peephole2
18816   [(set (match_operand 0 "register_operand" "")
18817         (match_operand 1 "const0_operand" ""))]
18818   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18819    && (! TARGET_USE_MOV0 || optimize_size)
18820    && GENERAL_REG_P (operands[0])
18821    && peep2_regno_dead_p (0, FLAGS_REG)"
18822   [(parallel [(set (match_dup 0) (const_int 0))
18823               (clobber (reg:CC FLAGS_REG))])]
18825   operands[0] = gen_lowpart (word_mode, operands[0]);
18828 (define_peephole2
18829   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18830         (const_int 0))]
18831   "(GET_MODE (operands[0]) == QImode
18832     || GET_MODE (operands[0]) == HImode)
18833    && (! TARGET_USE_MOV0 || optimize_size)
18834    && peep2_regno_dead_p (0, FLAGS_REG)"
18835   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18836               (clobber (reg:CC FLAGS_REG))])])
18838 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18839 (define_peephole2
18840   [(set (match_operand 0 "register_operand" "")
18841         (const_int -1))]
18842   "(GET_MODE (operands[0]) == HImode
18843     || GET_MODE (operands[0]) == SImode 
18844     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18845    && (optimize_size || TARGET_PENTIUM)
18846    && peep2_regno_dead_p (0, FLAGS_REG)"
18847   [(parallel [(set (match_dup 0) (const_int -1))
18848               (clobber (reg:CC FLAGS_REG))])]
18849   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18850                               operands[0]);")
18852 ;; Attempt to convert simple leas to adds. These can be created by
18853 ;; move expanders.
18854 (define_peephole2
18855   [(set (match_operand:SI 0 "register_operand" "")
18856         (plus:SI (match_dup 0)
18857                  (match_operand:SI 1 "nonmemory_operand" "")))]
18858   "peep2_regno_dead_p (0, FLAGS_REG)"
18859   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18860               (clobber (reg:CC FLAGS_REG))])]
18861   "")
18863 (define_peephole2
18864   [(set (match_operand:SI 0 "register_operand" "")
18865         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18866                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18867   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18868   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18869               (clobber (reg:CC FLAGS_REG))])]
18870   "operands[2] = gen_lowpart (SImode, operands[2]);")
18872 (define_peephole2
18873   [(set (match_operand:DI 0 "register_operand" "")
18874         (plus:DI (match_dup 0)
18875                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18876   "peep2_regno_dead_p (0, FLAGS_REG)"
18877   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18878               (clobber (reg:CC FLAGS_REG))])]
18879   "")
18881 (define_peephole2
18882   [(set (match_operand:SI 0 "register_operand" "")
18883         (mult:SI (match_dup 0)
18884                  (match_operand:SI 1 "const_int_operand" "")))]
18885   "exact_log2 (INTVAL (operands[1])) >= 0
18886    && peep2_regno_dead_p (0, FLAGS_REG)"
18887   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18888               (clobber (reg:CC FLAGS_REG))])]
18889   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18891 (define_peephole2
18892   [(set (match_operand:DI 0 "register_operand" "")
18893         (mult:DI (match_dup 0)
18894                  (match_operand:DI 1 "const_int_operand" "")))]
18895   "exact_log2 (INTVAL (operands[1])) >= 0
18896    && peep2_regno_dead_p (0, FLAGS_REG)"
18897   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18898               (clobber (reg:CC FLAGS_REG))])]
18899   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18901 (define_peephole2
18902   [(set (match_operand:SI 0 "register_operand" "")
18903         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18904                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18905   "exact_log2 (INTVAL (operands[2])) >= 0
18906    && REGNO (operands[0]) == REGNO (operands[1])
18907    && peep2_regno_dead_p (0, FLAGS_REG)"
18908   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18909               (clobber (reg:CC FLAGS_REG))])]
18910   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18912 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18913 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18914 ;; many CPUs it is also faster, since special hardware to avoid esp
18915 ;; dependencies is present.
18917 ;; While some of these conversions may be done using splitters, we use peepholes
18918 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18920 ;; Convert prologue esp subtractions to push.
18921 ;; We need register to push.  In order to keep verify_flow_info happy we have
18922 ;; two choices
18923 ;; - use scratch and clobber it in order to avoid dependencies
18924 ;; - use already live register
18925 ;; We can't use the second way right now, since there is no reliable way how to
18926 ;; verify that given register is live.  First choice will also most likely in
18927 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18928 ;; call clobbered registers are dead.  We may want to use base pointer as an
18929 ;; alternative when no register is available later.
18931 (define_peephole2
18932   [(match_scratch:SI 0 "r")
18933    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18934               (clobber (reg:CC FLAGS_REG))
18935               (clobber (mem:BLK (scratch)))])]
18936   "optimize_size || !TARGET_SUB_ESP_4"
18937   [(clobber (match_dup 0))
18938    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18939               (clobber (mem:BLK (scratch)))])])
18941 (define_peephole2
18942   [(match_scratch:SI 0 "r")
18943    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18944               (clobber (reg:CC FLAGS_REG))
18945               (clobber (mem:BLK (scratch)))])]
18946   "optimize_size || !TARGET_SUB_ESP_8"
18947   [(clobber (match_dup 0))
18948    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18949    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18950               (clobber (mem:BLK (scratch)))])])
18952 ;; Convert esp subtractions to push.
18953 (define_peephole2
18954   [(match_scratch:SI 0 "r")
18955    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
18956               (clobber (reg:CC FLAGS_REG))])]
18957   "optimize_size || !TARGET_SUB_ESP_4"
18958   [(clobber (match_dup 0))
18959    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18961 (define_peephole2
18962   [(match_scratch:SI 0 "r")
18963    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
18964               (clobber (reg:CC FLAGS_REG))])]
18965   "optimize_size || !TARGET_SUB_ESP_8"
18966   [(clobber (match_dup 0))
18967    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
18968    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
18970 ;; Convert epilogue deallocator to pop.
18971 (define_peephole2
18972   [(match_scratch:SI 0 "r")
18973    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18974               (clobber (reg:CC FLAGS_REG))
18975               (clobber (mem:BLK (scratch)))])]
18976   "optimize_size || !TARGET_ADD_ESP_4"
18977   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18978               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18979               (clobber (mem:BLK (scratch)))])]
18980   "")
18982 ;; Two pops case is tricky, since pop causes dependency on destination register.
18983 ;; We use two registers if available.
18984 (define_peephole2
18985   [(match_scratch:SI 0 "r")
18986    (match_scratch:SI 1 "r")
18987    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
18988               (clobber (reg:CC FLAGS_REG))
18989               (clobber (mem:BLK (scratch)))])]
18990   "optimize_size || !TARGET_ADD_ESP_8"
18991   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
18992               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
18993               (clobber (mem:BLK (scratch)))])
18994    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
18995               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
18996   "")
18998 (define_peephole2
18999   [(match_scratch:SI 0 "r")
19000    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19001               (clobber (reg:CC FLAGS_REG))
19002               (clobber (mem:BLK (scratch)))])]
19003   "optimize_size"
19004   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19005               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19006               (clobber (mem:BLK (scratch)))])
19007    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19008               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19009   "")
19011 ;; Convert esp additions to pop.
19012 (define_peephole2
19013   [(match_scratch:SI 0 "r")
19014    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19015               (clobber (reg:CC FLAGS_REG))])]
19016   ""
19017   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19018               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19019   "")
19021 ;; Two pops case is tricky, since pop causes dependency on destination register.
19022 ;; We use two registers if available.
19023 (define_peephole2
19024   [(match_scratch:SI 0 "r")
19025    (match_scratch:SI 1 "r")
19026    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19027               (clobber (reg:CC FLAGS_REG))])]
19028   ""
19029   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19030               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19031    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19032               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19033   "")
19035 (define_peephole2
19036   [(match_scratch:SI 0 "r")
19037    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19038               (clobber (reg:CC FLAGS_REG))])]
19039   "optimize_size"
19040   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19041               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19042    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19043               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19044   "")
19046 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19047 ;; required and register dies.  Similarly for 128 to plus -128.
19048 (define_peephole2
19049   [(set (match_operand 0 "flags_reg_operand" "")
19050         (match_operator 1 "compare_operator"
19051           [(match_operand 2 "register_operand" "")
19052            (match_operand 3 "const_int_operand" "")]))]
19053   "(INTVAL (operands[3]) == -1
19054     || INTVAL (operands[3]) == 1
19055     || INTVAL (operands[3]) == 128)
19056    && ix86_match_ccmode (insn, CCGCmode)
19057    && peep2_reg_dead_p (1, operands[2])"
19058   [(parallel [(set (match_dup 0)
19059                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19060               (clobber (match_dup 2))])]
19061   "")
19063 (define_peephole2
19064   [(match_scratch:DI 0 "r")
19065    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19066               (clobber (reg:CC FLAGS_REG))
19067               (clobber (mem:BLK (scratch)))])]
19068   "optimize_size || !TARGET_SUB_ESP_4"
19069   [(clobber (match_dup 0))
19070    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19071               (clobber (mem:BLK (scratch)))])])
19073 (define_peephole2
19074   [(match_scratch:DI 0 "r")
19075    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19076               (clobber (reg:CC FLAGS_REG))
19077               (clobber (mem:BLK (scratch)))])]
19078   "optimize_size || !TARGET_SUB_ESP_8"
19079   [(clobber (match_dup 0))
19080    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19081    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19082               (clobber (mem:BLK (scratch)))])])
19084 ;; Convert esp subtractions to push.
19085 (define_peephole2
19086   [(match_scratch:DI 0 "r")
19087    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19088               (clobber (reg:CC FLAGS_REG))])]
19089   "optimize_size || !TARGET_SUB_ESP_4"
19090   [(clobber (match_dup 0))
19091    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19093 (define_peephole2
19094   [(match_scratch:DI 0 "r")
19095    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19096               (clobber (reg:CC FLAGS_REG))])]
19097   "optimize_size || !TARGET_SUB_ESP_8"
19098   [(clobber (match_dup 0))
19099    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19100    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19102 ;; Convert epilogue deallocator to pop.
19103 (define_peephole2
19104   [(match_scratch:DI 0 "r")
19105    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19106               (clobber (reg:CC FLAGS_REG))
19107               (clobber (mem:BLK (scratch)))])]
19108   "optimize_size || !TARGET_ADD_ESP_4"
19109   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19110               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19111               (clobber (mem:BLK (scratch)))])]
19112   "")
19114 ;; Two pops case is tricky, since pop causes dependency on destination register.
19115 ;; We use two registers if available.
19116 (define_peephole2
19117   [(match_scratch:DI 0 "r")
19118    (match_scratch:DI 1 "r")
19119    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19120               (clobber (reg:CC FLAGS_REG))
19121               (clobber (mem:BLK (scratch)))])]
19122   "optimize_size || !TARGET_ADD_ESP_8"
19123   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19124               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19125               (clobber (mem:BLK (scratch)))])
19126    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19127               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19128   "")
19130 (define_peephole2
19131   [(match_scratch:DI 0 "r")
19132    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19133               (clobber (reg:CC FLAGS_REG))
19134               (clobber (mem:BLK (scratch)))])]
19135   "optimize_size"
19136   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19137               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19138               (clobber (mem:BLK (scratch)))])
19139    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19140               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19141   "")
19143 ;; Convert esp additions to pop.
19144 (define_peephole2
19145   [(match_scratch:DI 0 "r")
19146    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19147               (clobber (reg:CC FLAGS_REG))])]
19148   ""
19149   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19150               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19151   "")
19153 ;; Two pops case is tricky, since pop causes dependency on destination register.
19154 ;; We use two registers if available.
19155 (define_peephole2
19156   [(match_scratch:DI 0 "r")
19157    (match_scratch:DI 1 "r")
19158    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19159               (clobber (reg:CC FLAGS_REG))])]
19160   ""
19161   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19162               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19163    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19164               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19165   "")
19167 (define_peephole2
19168   [(match_scratch:DI 0 "r")
19169    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19170               (clobber (reg:CC FLAGS_REG))])]
19171   "optimize_size"
19172   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19173               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19174    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19175               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19176   "")
19178 ;; Convert imul by three, five and nine into lea
19179 (define_peephole2
19180   [(parallel
19181     [(set (match_operand:SI 0 "register_operand" "")
19182           (mult:SI (match_operand:SI 1 "register_operand" "")
19183                    (match_operand:SI 2 "const_int_operand" "")))
19184      (clobber (reg:CC FLAGS_REG))])]
19185   "INTVAL (operands[2]) == 3
19186    || INTVAL (operands[2]) == 5
19187    || INTVAL (operands[2]) == 9"
19188   [(set (match_dup 0)
19189         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19190                  (match_dup 1)))]
19191   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19193 (define_peephole2
19194   [(parallel
19195     [(set (match_operand:SI 0 "register_operand" "")
19196           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19197                    (match_operand:SI 2 "const_int_operand" "")))
19198      (clobber (reg:CC FLAGS_REG))])]
19199   "!optimize_size 
19200    && (INTVAL (operands[2]) == 3
19201        || INTVAL (operands[2]) == 5
19202        || INTVAL (operands[2]) == 9)"
19203   [(set (match_dup 0) (match_dup 1))
19204    (set (match_dup 0)
19205         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19206                  (match_dup 0)))]
19207   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19209 (define_peephole2
19210   [(parallel
19211     [(set (match_operand:DI 0 "register_operand" "")
19212           (mult:DI (match_operand:DI 1 "register_operand" "")
19213                    (match_operand:DI 2 "const_int_operand" "")))
19214      (clobber (reg:CC FLAGS_REG))])]
19215   "TARGET_64BIT
19216    && (INTVAL (operands[2]) == 3
19217        || INTVAL (operands[2]) == 5
19218        || INTVAL (operands[2]) == 9)"
19219   [(set (match_dup 0)
19220         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19221                  (match_dup 1)))]
19222   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19224 (define_peephole2
19225   [(parallel
19226     [(set (match_operand:DI 0 "register_operand" "")
19227           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19228                    (match_operand:DI 2 "const_int_operand" "")))
19229      (clobber (reg:CC FLAGS_REG))])]
19230   "TARGET_64BIT
19231    && !optimize_size 
19232    && (INTVAL (operands[2]) == 3
19233        || INTVAL (operands[2]) == 5
19234        || INTVAL (operands[2]) == 9)"
19235   [(set (match_dup 0) (match_dup 1))
19236    (set (match_dup 0)
19237         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19238                  (match_dup 0)))]
19239   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19241 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19242 ;; imul $32bit_imm, reg, reg is direct decoded.
19243 (define_peephole2
19244   [(match_scratch:DI 3 "r")
19245    (parallel [(set (match_operand:DI 0 "register_operand" "")
19246                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19247                             (match_operand:DI 2 "immediate_operand" "")))
19248               (clobber (reg:CC FLAGS_REG))])]
19249   "TARGET_K8 && !optimize_size
19250    && (GET_CODE (operands[2]) != CONST_INT
19251        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19252   [(set (match_dup 3) (match_dup 1))
19253    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19254               (clobber (reg:CC FLAGS_REG))])]
19257 (define_peephole2
19258   [(match_scratch:SI 3 "r")
19259    (parallel [(set (match_operand:SI 0 "register_operand" "")
19260                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19261                             (match_operand:SI 2 "immediate_operand" "")))
19262               (clobber (reg:CC FLAGS_REG))])]
19263   "TARGET_K8 && !optimize_size
19264    && (GET_CODE (operands[2]) != CONST_INT
19265        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19266   [(set (match_dup 3) (match_dup 1))
19267    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19268               (clobber (reg:CC FLAGS_REG))])]
19271 (define_peephole2
19272   [(match_scratch:SI 3 "r")
19273    (parallel [(set (match_operand:DI 0 "register_operand" "")
19274                    (zero_extend:DI
19275                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19276                               (match_operand:SI 2 "immediate_operand" ""))))
19277               (clobber (reg:CC FLAGS_REG))])]
19278   "TARGET_K8 && !optimize_size
19279    && (GET_CODE (operands[2]) != CONST_INT
19280        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19281   [(set (match_dup 3) (match_dup 1))
19282    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19283               (clobber (reg:CC FLAGS_REG))])]
19286 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19287 ;; Convert it into imul reg, reg
19288 ;; It would be better to force assembler to encode instruction using long
19289 ;; immediate, but there is apparently no way to do so.
19290 (define_peephole2
19291   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19292                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19293                             (match_operand:DI 2 "const_int_operand" "")))
19294               (clobber (reg:CC FLAGS_REG))])
19295    (match_scratch:DI 3 "r")]
19296   "TARGET_K8 && !optimize_size
19297    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19298   [(set (match_dup 3) (match_dup 2))
19299    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19300               (clobber (reg:CC FLAGS_REG))])]
19302   if (!rtx_equal_p (operands[0], operands[1]))
19303     emit_move_insn (operands[0], operands[1]);
19306 (define_peephole2
19307   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19308                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19309                             (match_operand:SI 2 "const_int_operand" "")))
19310               (clobber (reg:CC FLAGS_REG))])
19311    (match_scratch:SI 3 "r")]
19312   "TARGET_K8 && !optimize_size
19313    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19314   [(set (match_dup 3) (match_dup 2))
19315    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19316               (clobber (reg:CC FLAGS_REG))])]
19318   if (!rtx_equal_p (operands[0], operands[1]))
19319     emit_move_insn (operands[0], operands[1]);
19322 (define_peephole2
19323   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19324                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19325                             (match_operand:HI 2 "immediate_operand" "")))
19326               (clobber (reg:CC FLAGS_REG))])
19327    (match_scratch:HI 3 "r")]
19328   "TARGET_K8 && !optimize_size"
19329   [(set (match_dup 3) (match_dup 2))
19330    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19331               (clobber (reg:CC FLAGS_REG))])]
19333   if (!rtx_equal_p (operands[0], operands[1]))
19334     emit_move_insn (operands[0], operands[1]);
19337 ;; Call-value patterns last so that the wildcard operand does not
19338 ;; disrupt insn-recog's switch tables.
19340 (define_insn "*call_value_pop_0"
19341   [(set (match_operand 0 "" "")
19342         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19343               (match_operand:SI 2 "" "")))
19344    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19345                             (match_operand:SI 3 "immediate_operand" "")))]
19346   "!TARGET_64BIT"
19348   if (SIBLING_CALL_P (insn))
19349     return "jmp\t%P1";
19350   else
19351     return "call\t%P1";
19353   [(set_attr "type" "callv")])
19355 (define_insn "*call_value_pop_1"
19356   [(set (match_operand 0 "" "")
19357         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19358               (match_operand:SI 2 "" "")))
19359    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19360                             (match_operand:SI 3 "immediate_operand" "i")))]
19361   "!TARGET_64BIT"
19363   if (constant_call_address_operand (operands[1], Pmode))
19364     {
19365       if (SIBLING_CALL_P (insn))
19366         return "jmp\t%P1";
19367       else
19368         return "call\t%P1";
19369     }
19370   if (SIBLING_CALL_P (insn))
19371     return "jmp\t%A1";
19372   else
19373     return "call\t%A1";
19375   [(set_attr "type" "callv")])
19377 (define_insn "*call_value_0"
19378   [(set (match_operand 0 "" "")
19379         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19380               (match_operand:SI 2 "" "")))]
19381   "!TARGET_64BIT"
19383   if (SIBLING_CALL_P (insn))
19384     return "jmp\t%P1";
19385   else
19386     return "call\t%P1";
19388   [(set_attr "type" "callv")])
19390 (define_insn "*call_value_0_rex64"
19391   [(set (match_operand 0 "" "")
19392         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19393               (match_operand:DI 2 "const_int_operand" "")))]
19394   "TARGET_64BIT"
19396   if (SIBLING_CALL_P (insn))
19397     return "jmp\t%P1";
19398   else
19399     return "call\t%P1";
19401   [(set_attr "type" "callv")])
19403 (define_insn "*call_value_1"
19404   [(set (match_operand 0 "" "")
19405         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19406               (match_operand:SI 2 "" "")))]
19407   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19409   if (constant_call_address_operand (operands[1], Pmode))
19410     return "call\t%P1";
19411   return "call\t%A1";
19413   [(set_attr "type" "callv")])
19415 (define_insn "*sibcall_value_1"
19416   [(set (match_operand 0 "" "")
19417         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19418               (match_operand:SI 2 "" "")))]
19419   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19421   if (constant_call_address_operand (operands[1], Pmode))
19422     return "jmp\t%P1";
19423   return "jmp\t%A1";
19425   [(set_attr "type" "callv")])
19427 (define_insn "*call_value_1_rex64"
19428   [(set (match_operand 0 "" "")
19429         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19430               (match_operand:DI 2 "" "")))]
19431   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19433   if (constant_call_address_operand (operands[1], Pmode))
19434     return "call\t%P1";
19435   return "call\t%A1";
19437   [(set_attr "type" "callv")])
19439 (define_insn "*sibcall_value_1_rex64"
19440   [(set (match_operand 0 "" "")
19441         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19442               (match_operand:DI 2 "" "")))]
19443   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19444   "jmp\t%P1"
19445   [(set_attr "type" "callv")])
19447 (define_insn "*sibcall_value_1_rex64_v"
19448   [(set (match_operand 0 "" "")
19449         (call (mem:QI (reg:DI 40))
19450               (match_operand:DI 1 "" "")))]
19451   "SIBLING_CALL_P (insn) && TARGET_64BIT"
19452   "jmp\t*%%r11"
19453   [(set_attr "type" "callv")])
19455 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19456 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
19457 ;; caught for use by garbage collectors and the like.  Using an insn that
19458 ;; maps to SIGILL makes it more likely the program will rightfully die.
19459 ;; Keeping with tradition, "6" is in honor of #UD.
19460 (define_insn "trap"
19461   [(trap_if (const_int 1) (const_int 6))]
19462   ""
19463   "ud2"
19464   [(set_attr "length" "2")])
19466 (define_expand "sse_prologue_save"
19467   [(parallel [(set (match_operand:BLK 0 "" "")
19468                    (unspec:BLK [(reg:DI 21)
19469                                 (reg:DI 22)
19470                                 (reg:DI 23)
19471                                 (reg:DI 24)
19472                                 (reg:DI 25)
19473                                 (reg:DI 26)
19474                                 (reg:DI 27)
19475                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19476               (use (match_operand:DI 1 "register_operand" ""))
19477               (use (match_operand:DI 2 "immediate_operand" ""))
19478               (use (label_ref:DI (match_operand 3 "" "")))])]
19479   "TARGET_64BIT"
19480   "")
19482 (define_insn "*sse_prologue_save_insn"
19483   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19484                           (match_operand:DI 4 "const_int_operand" "n")))
19485         (unspec:BLK [(reg:DI 21)
19486                      (reg:DI 22)
19487                      (reg:DI 23)
19488                      (reg:DI 24)
19489                      (reg:DI 25)
19490                      (reg:DI 26)
19491                      (reg:DI 27)
19492                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19493    (use (match_operand:DI 1 "register_operand" "r"))
19494    (use (match_operand:DI 2 "const_int_operand" "i"))
19495    (use (label_ref:DI (match_operand 3 "" "X")))]
19496   "TARGET_64BIT
19497    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19498    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19499   "*
19501   int i;
19502   operands[0] = gen_rtx_MEM (Pmode,
19503                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19504   output_asm_insn (\"jmp\\t%A1\", operands);
19505   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19506     {
19507       operands[4] = adjust_address (operands[0], DImode, i*16);
19508       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19509       PUT_MODE (operands[4], TImode);
19510       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19511         output_asm_insn (\"rex\", operands);
19512       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19513     }
19514   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19515                              CODE_LABEL_NUMBER (operands[3]));
19516   RET;
19518   "
19519   [(set_attr "type" "other")
19520    (set_attr "length_immediate" "0")
19521    (set_attr "length_address" "0")
19522    (set_attr "length" "135")
19523    (set_attr "memory" "store")
19524    (set_attr "modrm" "0")
19525    (set_attr "mode" "DI")])
19527 (define_expand "prefetch"
19528   [(prefetch (match_operand 0 "address_operand" "")
19529              (match_operand:SI 1 "const_int_operand" "")
19530              (match_operand:SI 2 "const_int_operand" ""))]
19531   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19533   int rw = INTVAL (operands[1]);
19534   int locality = INTVAL (operands[2]);
19536   gcc_assert (rw == 0 || rw == 1);
19537   gcc_assert (locality >= 0 && locality <= 3);
19538   gcc_assert (GET_MODE (operands[0]) == Pmode
19539               || GET_MODE (operands[0]) == VOIDmode);
19541   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19542      supported by SSE counterpart or the SSE prefetch is not available
19543      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
19544      of locality.  */
19545   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19546     operands[2] = GEN_INT (3);
19547   else
19548     operands[1] = const0_rtx;
19551 (define_insn "*prefetch_sse"
19552   [(prefetch (match_operand:SI 0 "address_operand" "p")
19553              (const_int 0)
19554              (match_operand:SI 1 "const_int_operand" ""))]
19555   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19557   static const char * const patterns[4] = {
19558    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19559   };
19561   int locality = INTVAL (operands[1]);
19562   gcc_assert (locality >= 0 && locality <= 3);
19564   return patterns[locality];  
19566   [(set_attr "type" "sse")
19567    (set_attr "memory" "none")])
19569 (define_insn "*prefetch_sse_rex"
19570   [(prefetch (match_operand:DI 0 "address_operand" "p")
19571              (const_int 0)
19572              (match_operand:SI 1 "const_int_operand" ""))]
19573   "TARGET_PREFETCH_SSE && TARGET_64BIT"
19575   static const char * const patterns[4] = {
19576    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19577   };
19579   int locality = INTVAL (operands[1]);
19580   gcc_assert (locality >= 0 && locality <= 3);
19582   return patterns[locality];  
19584   [(set_attr "type" "sse")
19585    (set_attr "memory" "none")])
19587 (define_insn "*prefetch_3dnow"
19588   [(prefetch (match_operand:SI 0 "address_operand" "p")
19589              (match_operand:SI 1 "const_int_operand" "n")
19590              (const_int 3))]
19591   "TARGET_3DNOW && !TARGET_64BIT"
19593   if (INTVAL (operands[1]) == 0)
19594     return "prefetch\t%a0";
19595   else
19596     return "prefetchw\t%a0";
19598   [(set_attr "type" "mmx")
19599    (set_attr "memory" "none")])
19601 (define_insn "*prefetch_3dnow_rex"
19602   [(prefetch (match_operand:DI 0 "address_operand" "p")
19603              (match_operand:SI 1 "const_int_operand" "n")
19604              (const_int 3))]
19605   "TARGET_3DNOW && TARGET_64BIT"
19607   if (INTVAL (operands[1]) == 0)
19608     return "prefetch\t%a0";
19609   else
19610     return "prefetchw\t%a0";
19612   [(set_attr "type" "mmx")
19613    (set_attr "memory" "none")])
19615 (define_expand "stack_protect_set"
19616   [(match_operand 0 "memory_operand" "")
19617    (match_operand 1 "memory_operand" "")]
19618   ""
19620 #ifdef TARGET_THREAD_SSP_OFFSET
19621   if (TARGET_64BIT)
19622     emit_insn (gen_stack_tls_protect_set_di (operands[0],
19623                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19624   else
19625     emit_insn (gen_stack_tls_protect_set_si (operands[0],
19626                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19627 #else
19628   if (TARGET_64BIT)
19629     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
19630   else
19631     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
19632 #endif
19633   DONE;
19636 (define_insn "stack_protect_set_si"
19637   [(set (match_operand:SI 0 "memory_operand" "=m")
19638         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19639    (set (match_scratch:SI 2 "=&r") (const_int 0))
19640    (clobber (reg:CC FLAGS_REG))]
19641   ""
19642   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19643   [(set_attr "type" "multi")])
19645 (define_insn "stack_protect_set_di"
19646   [(set (match_operand:DI 0 "memory_operand" "=m")
19647         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
19648    (set (match_scratch:DI 2 "=&r") (const_int 0))
19649    (clobber (reg:CC FLAGS_REG))]
19650   "TARGET_64BIT"
19651   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19652   [(set_attr "type" "multi")])
19654 (define_insn "stack_tls_protect_set_si"
19655   [(set (match_operand:SI 0 "memory_operand" "=m")
19656         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19657    (set (match_scratch:SI 2 "=&r") (const_int 0))
19658    (clobber (reg:CC FLAGS_REG))]
19659   ""
19660   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
19661   [(set_attr "type" "multi")])
19663 (define_insn "stack_tls_protect_set_di"
19664   [(set (match_operand:DI 0 "memory_operand" "=m")
19665         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
19666    (set (match_scratch:DI 2 "=&r") (const_int 0))
19667    (clobber (reg:CC FLAGS_REG))]
19668   "TARGET_64BIT"
19669   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19670   [(set_attr "type" "multi")])
19672 (define_expand "stack_protect_test"
19673   [(match_operand 0 "memory_operand" "")
19674    (match_operand 1 "memory_operand" "")
19675    (match_operand 2 "" "")]
19676   ""
19678   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19679   ix86_compare_op0 = operands[0];
19680   ix86_compare_op1 = operands[1];
19681   ix86_compare_emitted = flags;
19683 #ifdef TARGET_THREAD_SSP_OFFSET
19684   if (TARGET_64BIT)
19685     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
19686                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19687   else
19688     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
19689                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
19690 #else
19691   if (TARGET_64BIT)
19692     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
19693   else
19694     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
19695 #endif
19696   emit_jump_insn (gen_beq (operands[2]));
19697   DONE;
19700 (define_insn "stack_protect_test_si"
19701   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19702         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19703                      (match_operand:SI 2 "memory_operand" "m")]
19704                     UNSPEC_SP_TEST))
19705    (clobber (match_scratch:SI 3 "=&r"))]
19706   ""
19707   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
19708   [(set_attr "type" "multi")])
19710 (define_insn "stack_protect_test_di"
19711   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19712         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19713                      (match_operand:DI 2 "memory_operand" "m")]
19714                     UNSPEC_SP_TEST))
19715    (clobber (match_scratch:DI 3 "=&r"))]
19716   "TARGET_64BIT"
19717   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
19718   [(set_attr "type" "multi")])
19720 (define_insn "stack_tls_protect_test_si"
19721   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19722         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
19723                      (match_operand:SI 2 "const_int_operand" "i")]
19724                     UNSPEC_SP_TLS_TEST))
19725    (clobber (match_scratch:SI 3 "=r"))]
19726   ""
19727   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
19728   [(set_attr "type" "multi")])
19730 (define_insn "stack_tls_protect_test_di"
19731   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
19732         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
19733                      (match_operand:DI 2 "const_int_operand" "i")]
19734                     UNSPEC_SP_TLS_TEST))
19735    (clobber (match_scratch:DI 3 "=r"))]
19736   "TARGET_64BIT"
19737   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
19738   [(set_attr "type" "multi")])
19740 (include "sse.md")
19741 (include "mmx.md")
19742 (include "sync.md")