2006-10-27 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / config / i386 / i386.md
blob4e2f9dd6197e461c4becae85cc95563b8e013ba2
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, 2006
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)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          30)
91    (UNSPEC_MASKMOV              31)
92    (UNSPEC_MOVMSK               32)
93    (UNSPEC_MOVNT                33)
94    (UNSPEC_MOVU                 34)
95    (UNSPEC_RCP                  35)
96    (UNSPEC_RSQRT                36)
97    (UNSPEC_SFENCE               37)
98    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                39)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDDQU                47)
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_TAN_ONE              82)
136    (UNSPEC_TAN_TAN              83)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
152    ; SSSE3
153    (UNSPEC_PSHUFB               120)
154    (UNSPEC_PSIGN                121)
155    (UNSPEC_PALIGNR              122)
156   ])
158 (define_constants
159   [(UNSPECV_BLOCKAGE            0)
160    (UNSPECV_STACK_PROBE         1)
161    (UNSPECV_EMMS                2)
162    (UNSPECV_LDMXCSR             3)
163    (UNSPECV_STMXCSR             4)
164    (UNSPECV_FEMMS               5)
165    (UNSPECV_CLFLUSH             6)
166    (UNSPECV_ALIGN               7)
167    (UNSPECV_MONITOR             8)
168    (UNSPECV_MWAIT               9)
169    (UNSPECV_CMPXCHG_1           10)
170    (UNSPECV_CMPXCHG_2           11)
171    (UNSPECV_XCHG                12)
172    (UNSPECV_LOCK                13)
173   ])
175 ;; Registers by name.
176 (define_constants
177   [(BP_REG                       6)
178    (SP_REG                       7)
179    (FLAGS_REG                   17)
180    (FPSR_REG                    18)
181    (FPCR_REG                    19)
182    (DIRFLAG_REG                 20)
183    (R11_REG                     41)
184   ])
186 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
187 ;; from i386.c.
189 ;; In C guard expressions, put expressions which may be compile-time
190 ;; constants first.  This allows for better optimization.  For
191 ;; example, write "TARGET_64BIT && reload_completed", not
192 ;; "reload_completed && TARGET_64BIT".
195 ;; Processor type.  This attribute must exactly match the processor_type
196 ;; enumeration in i386.h.
197 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,generic32,generic64"
198   (const (symbol_ref "ix86_tune")))
200 ;; A basic instruction type.  Refinements due to arguments to be
201 ;; provided in other attributes.
202 (define_attr "type"
203   "other,multi,
204    alu,alu1,negnot,imov,imovx,lea,
205    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
206    icmp,test,ibr,setcc,icmov,
207    push,pop,call,callv,leave,
208    str,cld,
209    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
210    sselog,sselog1,sseiadd,sseishft,sseimul,
211    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
212    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
213   (const_string "other"))
215 ;; Main data type used by the insn
216 (define_attr "mode"
217   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
218   (const_string "unknown"))
220 ;; The CPU unit operations uses.
221 (define_attr "unit" "integer,i387,sse,mmx,unknown"
222   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
223            (const_string "i387")
224          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
225                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
226            (const_string "sse")
227          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
228            (const_string "mmx")
229          (eq_attr "type" "other")
230            (const_string "unknown")]
231          (const_string "integer")))
233 ;; The (bounding maximum) length of an instruction immediate.
234 (define_attr "length_immediate" ""
235   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
236            (const_int 0)
237          (eq_attr "unit" "i387,sse,mmx")
238            (const_int 0)
239          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
240                           imul,icmp,push,pop")
241            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
242          (eq_attr "type" "imov,test")
243            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
244          (eq_attr "type" "call")
245            (if_then_else (match_operand 0 "constant_call_address_operand" "")
246              (const_int 4)
247              (const_int 0))
248          (eq_attr "type" "callv")
249            (if_then_else (match_operand 1 "constant_call_address_operand" "")
250              (const_int 4)
251              (const_int 0))
252          ;; We don't know the size before shorten_branches.  Expect
253          ;; the instruction to fit for better scheduling.
254          (eq_attr "type" "ibr")
255            (const_int 1)
256          ]
257          (symbol_ref "/* Update immediate_length and other attributes! */
258                       gcc_unreachable (),1")))
260 ;; The (bounding maximum) length of an instruction address.
261 (define_attr "length_address" ""
262   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
263            (const_int 0)
264          (and (eq_attr "type" "call")
265               (match_operand 0 "constant_call_address_operand" ""))
266              (const_int 0)
267          (and (eq_attr "type" "callv")
268               (match_operand 1 "constant_call_address_operand" ""))
269              (const_int 0)
270          ]
271          (symbol_ref "ix86_attr_length_address_default (insn)")))
273 ;; Set when length prefix is used.
274 (define_attr "prefix_data16" ""
275   (if_then_else (ior (eq_attr "mode" "HI")
276                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
277     (const_int 1)
278     (const_int 0)))
280 ;; Set when string REP prefix is used.
281 (define_attr "prefix_rep" "" 
282   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
283     (const_int 1)
284     (const_int 0)))
286 ;; Set when 0f opcode prefix is used.
287 (define_attr "prefix_0f" ""
288   (if_then_else 
289     (ior (eq_attr "type" "imovx,setcc,icmov")
290          (eq_attr "unit" "sse,mmx"))
291     (const_int 1)
292     (const_int 0)))
294 ;; Set when REX opcode prefix is used.
295 (define_attr "prefix_rex" ""
296   (cond [(and (eq_attr "mode" "DI")
297               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
298            (const_int 1)
299          (and (eq_attr "mode" "QI")
300               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
301                   (const_int 0)))
302            (const_int 1)
303          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
304              (const_int 0))
305            (const_int 1)
306         ]
307         (const_int 0)))
309 ;; Set when modrm byte is used.
310 (define_attr "modrm" ""
311   (cond [(eq_attr "type" "str,cld,leave")
312            (const_int 0)
313          (eq_attr "unit" "i387")
314            (const_int 0)
315          (and (eq_attr "type" "incdec")
316               (ior (match_operand:SI 1 "register_operand" "")
317                    (match_operand:HI 1 "register_operand" "")))
318            (const_int 0)
319          (and (eq_attr "type" "push")
320               (not (match_operand 1 "memory_operand" "")))
321            (const_int 0)
322          (and (eq_attr "type" "pop")
323               (not (match_operand 0 "memory_operand" "")))
324            (const_int 0)
325          (and (eq_attr "type" "imov")
326               (ior (and (match_operand 0 "register_operand" "")
327                         (match_operand 1 "immediate_operand" ""))
328                    (ior (and (match_operand 0 "ax_reg_operand" "")
329                              (match_operand 1 "memory_displacement_only_operand" ""))
330                         (and (match_operand 0 "memory_displacement_only_operand" "")
331                              (match_operand 1 "ax_reg_operand" "")))))
332            (const_int 0)
333          (and (eq_attr "type" "call")
334               (match_operand 0 "constant_call_address_operand" ""))
335              (const_int 0)
336          (and (eq_attr "type" "callv")
337               (match_operand 1 "constant_call_address_operand" ""))
338              (const_int 0)
339          ]
340          (const_int 1)))
342 ;; The (bounding maximum) length of an instruction in bytes.
343 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
344 ;; Later we may want to split them and compute proper length as for
345 ;; other insns.
346 (define_attr "length" ""
347   (cond [(eq_attr "type" "other,multi,fistp,frndint")
348            (const_int 16)
349          (eq_attr "type" "fcmp")
350            (const_int 4)
351          (eq_attr "unit" "i387")
352            (plus (const_int 2)
353                  (plus (attr "prefix_data16")
354                        (attr "length_address")))]
355          (plus (plus (attr "modrm")
356                      (plus (attr "prefix_0f")
357                            (plus (attr "prefix_rex")
358                                  (const_int 1))))
359                (plus (attr "prefix_rep")
360                      (plus (attr "prefix_data16")
361                            (plus (attr "length_immediate")
362                                  (attr "length_address")))))))
364 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
365 ;; `store' if there is a simple memory reference therein, or `unknown'
366 ;; if the instruction is complex.
368 (define_attr "memory" "none,load,store,both,unknown"
369   (cond [(eq_attr "type" "other,multi,str")
370            (const_string "unknown")
371          (eq_attr "type" "lea,fcmov,fpspc,cld")
372            (const_string "none")
373          (eq_attr "type" "fistp,leave")
374            (const_string "both")
375          (eq_attr "type" "frndint")
376            (const_string "load")
377          (eq_attr "type" "push")
378            (if_then_else (match_operand 1 "memory_operand" "")
379              (const_string "both")
380              (const_string "store"))
381          (eq_attr "type" "pop")
382            (if_then_else (match_operand 0 "memory_operand" "")
383              (const_string "both")
384              (const_string "load"))
385          (eq_attr "type" "setcc")
386            (if_then_else (match_operand 0 "memory_operand" "")
387              (const_string "store")
388              (const_string "none"))
389          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
390            (if_then_else (ior (match_operand 0 "memory_operand" "")
391                               (match_operand 1 "memory_operand" ""))
392              (const_string "load")
393              (const_string "none"))
394          (eq_attr "type" "ibr")
395            (if_then_else (match_operand 0 "memory_operand" "")
396              (const_string "load")
397              (const_string "none"))
398          (eq_attr "type" "call")
399            (if_then_else (match_operand 0 "constant_call_address_operand" "")
400              (const_string "none")
401              (const_string "load"))
402          (eq_attr "type" "callv")
403            (if_then_else (match_operand 1 "constant_call_address_operand" "")
404              (const_string "none")
405              (const_string "load"))
406          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
407               (match_operand 1 "memory_operand" ""))
408            (const_string "both")
409          (and (match_operand 0 "memory_operand" "")
410               (match_operand 1 "memory_operand" ""))
411            (const_string "both")
412          (match_operand 0 "memory_operand" "")
413            (const_string "store")
414          (match_operand 1 "memory_operand" "")
415            (const_string "load")
416          (and (eq_attr "type"
417                  "!alu1,negnot,ishift1,
418                    imov,imovx,icmp,test,
419                    fmov,fcmp,fsgn,
420                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
421                    mmx,mmxmov,mmxcmp,mmxcvt")
422               (match_operand 2 "memory_operand" ""))
423            (const_string "load")
424          (and (eq_attr "type" "icmov")
425               (match_operand 3 "memory_operand" ""))
426            (const_string "load")
427         ]
428         (const_string "none")))
430 ;; Indicates if an instruction has both an immediate and a displacement.
432 (define_attr "imm_disp" "false,true,unknown"
433   (cond [(eq_attr "type" "other,multi")
434            (const_string "unknown")
435          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
436               (and (match_operand 0 "memory_displacement_operand" "")
437                    (match_operand 1 "immediate_operand" "")))
438            (const_string "true")
439          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
440               (and (match_operand 0 "memory_displacement_operand" "")
441                    (match_operand 2 "immediate_operand" "")))
442            (const_string "true")
443         ]
444         (const_string "false")))
446 ;; Indicates if an FP operation has an integer source.
448 (define_attr "fp_int_src" "false,true"
449   (const_string "false"))
451 ;; Defines rounding mode of an FP operation.
453 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
454   (const_string "any"))
456 ;; Describe a user's asm statement.
457 (define_asm_attributes
458   [(set_attr "length" "128")
459    (set_attr "type" "multi")])
461 ;; All x87 floating point modes
462 (define_mode_macro X87MODEF [SF DF XF])
464 ;; All integer modes handled by x87 fisttp operator.
465 (define_mode_macro X87MODEI [HI SI DI])
467 ;; All integer modes handled by integer x87 operators.
468 (define_mode_macro X87MODEI12 [HI SI])
470 ;; All SSE floating point modes
471 (define_mode_macro SSEMODEF [SF DF])
473 ;; All integer modes handled by SSE cvtts?2si* operators.
474 (define_mode_macro SSEMODEI24 [SI DI])
477 ;; Scheduling descriptions
479 (include "pentium.md")
480 (include "ppro.md")
481 (include "k6.md")
482 (include "athlon.md")
483 (include "geode.md")
486 ;; Operand and operator predicates and constraints
488 (include "predicates.md")
489 (include "constraints.md")
492 ;; Compare instructions.
494 ;; All compare insns have expanders that save the operands away without
495 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
496 ;; after the cmp) will actually emit the cmpM.
498 (define_expand "cmpti"
499   [(set (reg:CC FLAGS_REG)
500         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
501                     (match_operand:TI 1 "x86_64_general_operand" "")))]
502   "TARGET_64BIT"
504   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
505     operands[0] = force_reg (TImode, operands[0]);
506   ix86_compare_op0 = operands[0];
507   ix86_compare_op1 = operands[1];
508   DONE;
511 (define_expand "cmpdi"
512   [(set (reg:CC FLAGS_REG)
513         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
514                     (match_operand:DI 1 "x86_64_general_operand" "")))]
515   ""
517   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
518     operands[0] = force_reg (DImode, operands[0]);
519   ix86_compare_op0 = operands[0];
520   ix86_compare_op1 = operands[1];
521   DONE;
524 (define_expand "cmpsi"
525   [(set (reg:CC FLAGS_REG)
526         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
527                     (match_operand:SI 1 "general_operand" "")))]
528   ""
530   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
531     operands[0] = force_reg (SImode, operands[0]);
532   ix86_compare_op0 = operands[0];
533   ix86_compare_op1 = operands[1];
534   DONE;
537 (define_expand "cmphi"
538   [(set (reg:CC FLAGS_REG)
539         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
540                     (match_operand:HI 1 "general_operand" "")))]
541   ""
543   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
544     operands[0] = force_reg (HImode, operands[0]);
545   ix86_compare_op0 = operands[0];
546   ix86_compare_op1 = operands[1];
547   DONE;
550 (define_expand "cmpqi"
551   [(set (reg:CC FLAGS_REG)
552         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
553                     (match_operand:QI 1 "general_operand" "")))]
554   "TARGET_QIMODE_MATH"
556   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
557     operands[0] = force_reg (QImode, operands[0]);
558   ix86_compare_op0 = operands[0];
559   ix86_compare_op1 = operands[1];
560   DONE;
563 (define_insn "cmpdi_ccno_1_rex64"
564   [(set (reg FLAGS_REG)
565         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
566                  (match_operand:DI 1 "const0_operand" "n,n")))]
567   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
568   "@
569    test{q}\t{%0, %0|%0, %0}
570    cmp{q}\t{%1, %0|%0, %1}"
571   [(set_attr "type" "test,icmp")
572    (set_attr "length_immediate" "0,1")
573    (set_attr "mode" "DI")])
575 (define_insn "*cmpdi_minus_1_rex64"
576   [(set (reg FLAGS_REG)
577         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
578                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
579                  (const_int 0)))]
580   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
581   "cmp{q}\t{%1, %0|%0, %1}"
582   [(set_attr "type" "icmp")
583    (set_attr "mode" "DI")])
585 (define_expand "cmpdi_1_rex64"
586   [(set (reg:CC FLAGS_REG)
587         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
588                     (match_operand:DI 1 "general_operand" "")))]
589   "TARGET_64BIT"
590   "")
592 (define_insn "cmpdi_1_insn_rex64"
593   [(set (reg FLAGS_REG)
594         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
595                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
596   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
597   "cmp{q}\t{%1, %0|%0, %1}"
598   [(set_attr "type" "icmp")
599    (set_attr "mode" "DI")])
602 (define_insn "*cmpsi_ccno_1"
603   [(set (reg FLAGS_REG)
604         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
605                  (match_operand:SI 1 "const0_operand" "n,n")))]
606   "ix86_match_ccmode (insn, CCNOmode)"
607   "@
608    test{l}\t{%0, %0|%0, %0}
609    cmp{l}\t{%1, %0|%0, %1}"
610   [(set_attr "type" "test,icmp")
611    (set_attr "length_immediate" "0,1")
612    (set_attr "mode" "SI")])
614 (define_insn "*cmpsi_minus_1"
615   [(set (reg FLAGS_REG)
616         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
617                            (match_operand:SI 1 "general_operand" "ri,mr"))
618                  (const_int 0)))]
619   "ix86_match_ccmode (insn, CCGOCmode)"
620   "cmp{l}\t{%1, %0|%0, %1}"
621   [(set_attr "type" "icmp")
622    (set_attr "mode" "SI")])
624 (define_expand "cmpsi_1"
625   [(set (reg:CC FLAGS_REG)
626         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
627                     (match_operand:SI 1 "general_operand" "ri,mr")))]
628   ""
629   "")
631 (define_insn "*cmpsi_1_insn"
632   [(set (reg FLAGS_REG)
633         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
634                  (match_operand:SI 1 "general_operand" "ri,mr")))]
635   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
636     && ix86_match_ccmode (insn, CCmode)"
637   "cmp{l}\t{%1, %0|%0, %1}"
638   [(set_attr "type" "icmp")
639    (set_attr "mode" "SI")])
641 (define_insn "*cmphi_ccno_1"
642   [(set (reg FLAGS_REG)
643         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
644                  (match_operand:HI 1 "const0_operand" "n,n")))]
645   "ix86_match_ccmode (insn, CCNOmode)"
646   "@
647    test{w}\t{%0, %0|%0, %0}
648    cmp{w}\t{%1, %0|%0, %1}"
649   [(set_attr "type" "test,icmp")
650    (set_attr "length_immediate" "0,1")
651    (set_attr "mode" "HI")])
653 (define_insn "*cmphi_minus_1"
654   [(set (reg FLAGS_REG)
655         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
656                            (match_operand:HI 1 "general_operand" "ri,mr"))
657                  (const_int 0)))]
658   "ix86_match_ccmode (insn, CCGOCmode)"
659   "cmp{w}\t{%1, %0|%0, %1}"
660   [(set_attr "type" "icmp")
661    (set_attr "mode" "HI")])
663 (define_insn "*cmphi_1"
664   [(set (reg FLAGS_REG)
665         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
666                  (match_operand:HI 1 "general_operand" "ri,mr")))]
667   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
668    && ix86_match_ccmode (insn, CCmode)"
669   "cmp{w}\t{%1, %0|%0, %1}"
670   [(set_attr "type" "icmp")
671    (set_attr "mode" "HI")])
673 (define_insn "*cmpqi_ccno_1"
674   [(set (reg FLAGS_REG)
675         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
676                  (match_operand:QI 1 "const0_operand" "n,n")))]
677   "ix86_match_ccmode (insn, CCNOmode)"
678   "@
679    test{b}\t{%0, %0|%0, %0}
680    cmp{b}\t{$0, %0|%0, 0}"
681   [(set_attr "type" "test,icmp")
682    (set_attr "length_immediate" "0,1")
683    (set_attr "mode" "QI")])
685 (define_insn "*cmpqi_1"
686   [(set (reg FLAGS_REG)
687         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
688                  (match_operand:QI 1 "general_operand" "qi,mq")))]
689   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
690     && ix86_match_ccmode (insn, CCmode)"
691   "cmp{b}\t{%1, %0|%0, %1}"
692   [(set_attr "type" "icmp")
693    (set_attr "mode" "QI")])
695 (define_insn "*cmpqi_minus_1"
696   [(set (reg FLAGS_REG)
697         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
698                            (match_operand:QI 1 "general_operand" "qi,mq"))
699                  (const_int 0)))]
700   "ix86_match_ccmode (insn, CCGOCmode)"
701   "cmp{b}\t{%1, %0|%0, %1}"
702   [(set_attr "type" "icmp")
703    (set_attr "mode" "QI")])
705 (define_insn "*cmpqi_ext_1"
706   [(set (reg FLAGS_REG)
707         (compare
708           (match_operand:QI 0 "general_operand" "Qm")
709           (subreg:QI
710             (zero_extract:SI
711               (match_operand 1 "ext_register_operand" "Q")
712               (const_int 8)
713               (const_int 8)) 0)))]
714   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
715   "cmp{b}\t{%h1, %0|%0, %h1}"
716   [(set_attr "type" "icmp")
717    (set_attr "mode" "QI")])
719 (define_insn "*cmpqi_ext_1_rex64"
720   [(set (reg FLAGS_REG)
721         (compare
722           (match_operand:QI 0 "register_operand" "Q")
723           (subreg:QI
724             (zero_extract:SI
725               (match_operand 1 "ext_register_operand" "Q")
726               (const_int 8)
727               (const_int 8)) 0)))]
728   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
729   "cmp{b}\t{%h1, %0|%0, %h1}"
730   [(set_attr "type" "icmp")
731    (set_attr "mode" "QI")])
733 (define_insn "*cmpqi_ext_2"
734   [(set (reg FLAGS_REG)
735         (compare
736           (subreg:QI
737             (zero_extract:SI
738               (match_operand 0 "ext_register_operand" "Q")
739               (const_int 8)
740               (const_int 8)) 0)
741           (match_operand:QI 1 "const0_operand" "n")))]
742   "ix86_match_ccmode (insn, CCNOmode)"
743   "test{b}\t%h0, %h0"
744   [(set_attr "type" "test")
745    (set_attr "length_immediate" "0")
746    (set_attr "mode" "QI")])
748 (define_expand "cmpqi_ext_3"
749   [(set (reg:CC FLAGS_REG)
750         (compare:CC
751           (subreg:QI
752             (zero_extract:SI
753               (match_operand 0 "ext_register_operand" "")
754               (const_int 8)
755               (const_int 8)) 0)
756           (match_operand:QI 1 "general_operand" "")))]
757   ""
758   "")
760 (define_insn "cmpqi_ext_3_insn"
761   [(set (reg FLAGS_REG)
762         (compare
763           (subreg:QI
764             (zero_extract:SI
765               (match_operand 0 "ext_register_operand" "Q")
766               (const_int 8)
767               (const_int 8)) 0)
768           (match_operand:QI 1 "general_operand" "Qmn")))]
769   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
770   "cmp{b}\t{%1, %h0|%h0, %1}"
771   [(set_attr "type" "icmp")
772    (set_attr "mode" "QI")])
774 (define_insn "cmpqi_ext_3_insn_rex64"
775   [(set (reg FLAGS_REG)
776         (compare
777           (subreg:QI
778             (zero_extract:SI
779               (match_operand 0 "ext_register_operand" "Q")
780               (const_int 8)
781               (const_int 8)) 0)
782           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
783   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
784   "cmp{b}\t{%1, %h0|%h0, %1}"
785   [(set_attr "type" "icmp")
786    (set_attr "mode" "QI")])
788 (define_insn "*cmpqi_ext_4"
789   [(set (reg FLAGS_REG)
790         (compare
791           (subreg:QI
792             (zero_extract:SI
793               (match_operand 0 "ext_register_operand" "Q")
794               (const_int 8)
795               (const_int 8)) 0)
796           (subreg:QI
797             (zero_extract:SI
798               (match_operand 1 "ext_register_operand" "Q")
799               (const_int 8)
800               (const_int 8)) 0)))]
801   "ix86_match_ccmode (insn, CCmode)"
802   "cmp{b}\t{%h1, %h0|%h0, %h1}"
803   [(set_attr "type" "icmp")
804    (set_attr "mode" "QI")])
806 ;; These implement float point compares.
807 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
808 ;; which would allow mix and match FP modes on the compares.  Which is what
809 ;; the old patterns did, but with many more of them.
811 (define_expand "cmpxf"
812   [(set (reg:CC FLAGS_REG)
813         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
814                     (match_operand:XF 1 "nonmemory_operand" "")))]
815   "TARGET_80387"
817   ix86_compare_op0 = operands[0];
818   ix86_compare_op1 = operands[1];
819   DONE;
822 (define_expand "cmpdf"
823   [(set (reg:CC FLAGS_REG)
824         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
825                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
826   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
828   ix86_compare_op0 = operands[0];
829   ix86_compare_op1 = operands[1];
830   DONE;
833 (define_expand "cmpsf"
834   [(set (reg:CC FLAGS_REG)
835         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
836                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
837   "TARGET_80387 || TARGET_SSE_MATH"
839   ix86_compare_op0 = operands[0];
840   ix86_compare_op1 = operands[1];
841   DONE;
844 ;; FP compares, step 1:
845 ;; Set the FP condition codes.
847 ;; CCFPmode     compare with exceptions
848 ;; CCFPUmode    compare with no exceptions
850 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
851 ;; used to manage the reg stack popping would not be preserved.
853 (define_insn "*cmpfp_0"
854   [(set (match_operand:HI 0 "register_operand" "=a")
855         (unspec:HI
856           [(compare:CCFP
857              (match_operand 1 "register_operand" "f")
858              (match_operand 2 "const0_operand" "X"))]
859         UNSPEC_FNSTSW))]
860   "TARGET_80387
861    && FLOAT_MODE_P (GET_MODE (operands[1]))
862    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
863   "* return output_fp_compare (insn, operands, 0, 0);"
864   [(set_attr "type" "multi")
865    (set_attr "unit" "i387")
866    (set (attr "mode")
867      (cond [(match_operand:SF 1 "" "")
868               (const_string "SF")
869             (match_operand:DF 1 "" "")
870               (const_string "DF")
871            ]
872            (const_string "XF")))])
874 (define_insn "*cmpfp_sf"
875   [(set (match_operand:HI 0 "register_operand" "=a")
876         (unspec:HI
877           [(compare:CCFP
878              (match_operand:SF 1 "register_operand" "f")
879              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
880           UNSPEC_FNSTSW))]
881   "TARGET_80387"
882   "* return output_fp_compare (insn, operands, 0, 0);"
883   [(set_attr "type" "multi")
884    (set_attr "unit" "i387")
885    (set_attr "mode" "SF")])
887 (define_insn "*cmpfp_df"
888   [(set (match_operand:HI 0 "register_operand" "=a")
889         (unspec:HI
890           [(compare:CCFP
891              (match_operand:DF 1 "register_operand" "f")
892              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
893           UNSPEC_FNSTSW))]
894   "TARGET_80387"
895   "* return output_fp_compare (insn, operands, 0, 0);"
896   [(set_attr "type" "multi")
897    (set_attr "unit" "i387")
898    (set_attr "mode" "DF")])
900 (define_insn "*cmpfp_xf"
901   [(set (match_operand:HI 0 "register_operand" "=a")
902         (unspec:HI
903           [(compare:CCFP
904              (match_operand:XF 1 "register_operand" "f")
905              (match_operand:XF 2 "register_operand" "f"))]
906           UNSPEC_FNSTSW))]
907   "TARGET_80387"
908   "* return output_fp_compare (insn, operands, 0, 0);"
909   [(set_attr "type" "multi")
910    (set_attr "unit" "i387")
911    (set_attr "mode" "XF")])
913 (define_insn "*cmpfp_u"
914   [(set (match_operand:HI 0 "register_operand" "=a")
915         (unspec:HI
916           [(compare:CCFPU
917              (match_operand 1 "register_operand" "f")
918              (match_operand 2 "register_operand" "f"))]
919           UNSPEC_FNSTSW))]
920   "TARGET_80387
921    && FLOAT_MODE_P (GET_MODE (operands[1]))
922    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
923   "* return output_fp_compare (insn, operands, 0, 1);"
924   [(set_attr "type" "multi")
925    (set_attr "unit" "i387")
926    (set (attr "mode")
927      (cond [(match_operand:SF 1 "" "")
928               (const_string "SF")
929             (match_operand:DF 1 "" "")
930               (const_string "DF")
931            ]
932            (const_string "XF")))])
934 (define_insn "*cmpfp_<mode>"
935   [(set (match_operand:HI 0 "register_operand" "=a")
936         (unspec:HI
937           [(compare:CCFP
938              (match_operand 1 "register_operand" "f")
939              (match_operator 3 "float_operator"
940                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
941           UNSPEC_FNSTSW))]
942   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
943    && FLOAT_MODE_P (GET_MODE (operands[1]))
944    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
945   "* return output_fp_compare (insn, operands, 0, 0);"
946   [(set_attr "type" "multi")
947    (set_attr "unit" "i387")
948    (set_attr "fp_int_src" "true")
949    (set_attr "mode" "<MODE>")])
951 ;; FP compares, step 2
952 ;; Move the fpsw to ax.
954 (define_insn "x86_fnstsw_1"
955   [(set (match_operand:HI 0 "register_operand" "=a")
956         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
957   "TARGET_80387"
958   "fnstsw\t%0"
959   [(set_attr "length" "2")
960    (set_attr "mode" "SI")
961    (set_attr "unit" "i387")])
963 ;; FP compares, step 3
964 ;; Get ax into flags, general case.
966 (define_insn "x86_sahf_1"
967   [(set (reg:CC FLAGS_REG)
968         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
969   "!TARGET_64BIT"
970   "sahf"
971   [(set_attr "length" "1")
972    (set_attr "athlon_decode" "vector")
973    (set_attr "mode" "SI")])
975 ;; Pentium Pro can do steps 1 through 3 in one go.
977 (define_insn "*cmpfp_i_mixed"
978   [(set (reg:CCFP FLAGS_REG)
979         (compare:CCFP (match_operand 0 "register_operand" "f,x")
980                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
981   "TARGET_MIX_SSE_I387
982    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
983    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
984   "* return output_fp_compare (insn, operands, 1, 0);"
985   [(set_attr "type" "fcmp,ssecomi")
986    (set (attr "mode")
987      (if_then_else (match_operand:SF 1 "" "")
988         (const_string "SF")
989         (const_string "DF")))
990    (set_attr "athlon_decode" "vector")])
992 (define_insn "*cmpfp_i_sse"
993   [(set (reg:CCFP FLAGS_REG)
994         (compare:CCFP (match_operand 0 "register_operand" "x")
995                       (match_operand 1 "nonimmediate_operand" "xm")))]
996   "TARGET_SSE_MATH
997    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
998    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
999   "* return output_fp_compare (insn, operands, 1, 0);"
1000   [(set_attr "type" "ssecomi")
1001    (set (attr "mode")
1002      (if_then_else (match_operand:SF 1 "" "")
1003         (const_string "SF")
1004         (const_string "DF")))
1005    (set_attr "athlon_decode" "vector")])
1007 (define_insn "*cmpfp_i_i387"
1008   [(set (reg:CCFP FLAGS_REG)
1009         (compare:CCFP (match_operand 0 "register_operand" "f")
1010                       (match_operand 1 "register_operand" "f")))]
1011   "TARGET_80387 && TARGET_CMOVE
1012    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1013    && FLOAT_MODE_P (GET_MODE (operands[0]))
1014    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1015   "* return output_fp_compare (insn, operands, 1, 0);"
1016   [(set_attr "type" "fcmp")
1017    (set (attr "mode")
1018      (cond [(match_operand:SF 1 "" "")
1019               (const_string "SF")
1020             (match_operand:DF 1 "" "")
1021               (const_string "DF")
1022            ]
1023            (const_string "XF")))
1024    (set_attr "athlon_decode" "vector")])
1026 (define_insn "*cmpfp_iu_mixed"
1027   [(set (reg:CCFPU FLAGS_REG)
1028         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1029                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1030   "TARGET_MIX_SSE_I387
1031    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1032    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033   "* return output_fp_compare (insn, operands, 1, 1);"
1034   [(set_attr "type" "fcmp,ssecomi")
1035    (set (attr "mode")
1036      (if_then_else (match_operand:SF 1 "" "")
1037         (const_string "SF")
1038         (const_string "DF")))
1039    (set_attr "athlon_decode" "vector")])
1041 (define_insn "*cmpfp_iu_sse"
1042   [(set (reg:CCFPU FLAGS_REG)
1043         (compare:CCFPU (match_operand 0 "register_operand" "x")
1044                        (match_operand 1 "nonimmediate_operand" "xm")))]
1045   "TARGET_SSE_MATH
1046    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1047    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1048   "* return output_fp_compare (insn, operands, 1, 1);"
1049   [(set_attr "type" "ssecomi")
1050    (set (attr "mode")
1051      (if_then_else (match_operand:SF 1 "" "")
1052         (const_string "SF")
1053         (const_string "DF")))
1054    (set_attr "athlon_decode" "vector")])
1056 (define_insn "*cmpfp_iu_387"
1057   [(set (reg:CCFPU FLAGS_REG)
1058         (compare:CCFPU (match_operand 0 "register_operand" "f")
1059                        (match_operand 1 "register_operand" "f")))]
1060   "TARGET_80387 && TARGET_CMOVE
1061    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1062    && FLOAT_MODE_P (GET_MODE (operands[0]))
1063    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1064   "* return output_fp_compare (insn, operands, 1, 1);"
1065   [(set_attr "type" "fcmp")
1066    (set (attr "mode")
1067      (cond [(match_operand:SF 1 "" "")
1068               (const_string "SF")
1069             (match_operand:DF 1 "" "")
1070               (const_string "DF")
1071            ]
1072            (const_string "XF")))
1073    (set_attr "athlon_decode" "vector")])
1075 ;; Move instructions.
1077 ;; General case of fullword move.
1079 (define_expand "movsi"
1080   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1081         (match_operand:SI 1 "general_operand" ""))]
1082   ""
1083   "ix86_expand_move (SImode, operands); DONE;")
1085 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1086 ;; general_operand.
1088 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1089 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1090 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1091 ;; targets without our curiosities, and it is just as easy to represent
1092 ;; this differently.
1094 (define_insn "*pushsi2"
1095   [(set (match_operand:SI 0 "push_operand" "=<")
1096         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1097   "!TARGET_64BIT"
1098   "push{l}\t%1"
1099   [(set_attr "type" "push")
1100    (set_attr "mode" "SI")])
1102 ;; For 64BIT abi we always round up to 8 bytes.
1103 (define_insn "*pushsi2_rex64"
1104   [(set (match_operand:SI 0 "push_operand" "=X")
1105         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1106   "TARGET_64BIT"
1107   "push{q}\t%q1"
1108   [(set_attr "type" "push")
1109    (set_attr "mode" "SI")])
1111 (define_insn "*pushsi2_prologue"
1112   [(set (match_operand:SI 0 "push_operand" "=<")
1113         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1114    (clobber (mem:BLK (scratch)))]
1115   "!TARGET_64BIT"
1116   "push{l}\t%1"
1117   [(set_attr "type" "push")
1118    (set_attr "mode" "SI")])
1120 (define_insn "*popsi1_epilogue"
1121   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1122         (mem:SI (reg:SI SP_REG)))
1123    (set (reg:SI SP_REG)
1124         (plus:SI (reg:SI SP_REG) (const_int 4)))
1125    (clobber (mem:BLK (scratch)))]
1126   "!TARGET_64BIT"
1127   "pop{l}\t%0"
1128   [(set_attr "type" "pop")
1129    (set_attr "mode" "SI")])
1131 (define_insn "popsi1"
1132   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1133         (mem:SI (reg:SI SP_REG)))
1134    (set (reg:SI SP_REG)
1135         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1136   "!TARGET_64BIT"
1137   "pop{l}\t%0"
1138   [(set_attr "type" "pop")
1139    (set_attr "mode" "SI")])
1141 (define_insn "*movsi_xor"
1142   [(set (match_operand:SI 0 "register_operand" "=r")
1143         (match_operand:SI 1 "const0_operand" "i"))
1144    (clobber (reg:CC FLAGS_REG))]
1145   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1146   "xor{l}\t{%0, %0|%0, %0}"
1147   [(set_attr "type" "alu1")
1148    (set_attr "mode" "SI")
1149    (set_attr "length_immediate" "0")])
1151 (define_insn "*movsi_or"
1152   [(set (match_operand:SI 0 "register_operand" "=r")
1153         (match_operand:SI 1 "immediate_operand" "i"))
1154    (clobber (reg:CC FLAGS_REG))]
1155   "reload_completed
1156    && operands[1] == constm1_rtx
1157    && (TARGET_PENTIUM || optimize_size)"
1159   operands[1] = constm1_rtx;
1160   return "or{l}\t{%1, %0|%0, %1}";
1162   [(set_attr "type" "alu1")
1163    (set_attr "mode" "SI")
1164    (set_attr "length_immediate" "1")])
1166 (define_insn "*movsi_1"
1167   [(set (match_operand:SI 0 "nonimmediate_operand"
1168                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1169         (match_operand:SI 1 "general_operand"
1170                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1171   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1173   switch (get_attr_type (insn))
1174     {
1175     case TYPE_SSELOG1:
1176       if (get_attr_mode (insn) == MODE_TI)
1177         return "pxor\t%0, %0";
1178       return "xorps\t%0, %0";
1180     case TYPE_SSEMOV:
1181       switch (get_attr_mode (insn))
1182         {
1183         case MODE_TI:
1184           return "movdqa\t{%1, %0|%0, %1}";
1185         case MODE_V4SF:
1186           return "movaps\t{%1, %0|%0, %1}";
1187         case MODE_SI:
1188           return "movd\t{%1, %0|%0, %1}";
1189         case MODE_SF:
1190           return "movss\t{%1, %0|%0, %1}";
1191         default:
1192           gcc_unreachable ();
1193         }
1195     case TYPE_MMXADD:
1196       return "pxor\t%0, %0";
1198     case TYPE_MMXMOV:
1199       if (get_attr_mode (insn) == MODE_DI)
1200         return "movq\t{%1, %0|%0, %1}";
1201       return "movd\t{%1, %0|%0, %1}";
1203     case TYPE_LEA:
1204       return "lea{l}\t{%1, %0|%0, %1}";
1206     default:
1207       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1208       return "mov{l}\t{%1, %0|%0, %1}";
1209     }
1211   [(set (attr "type")
1212      (cond [(eq_attr "alternative" "2")
1213               (const_string "mmxadd")
1214             (eq_attr "alternative" "3,4,5")
1215               (const_string "mmxmov")
1216             (eq_attr "alternative" "6")
1217               (const_string "sselog1")
1218             (eq_attr "alternative" "7,8,9,10,11")
1219               (const_string "ssemov")
1220             (match_operand:DI 1 "pic_32bit_operand" "")
1221               (const_string "lea")
1222            ]
1223            (const_string "imov")))
1224    (set (attr "mode")
1225      (cond [(eq_attr "alternative" "2,3")
1226               (const_string "DI")
1227             (eq_attr "alternative" "6,7")
1228               (if_then_else
1229                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1230                 (const_string "V4SF")
1231                 (const_string "TI"))
1232             (and (eq_attr "alternative" "8,9,10,11")
1233                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1234               (const_string "SF")
1235            ]
1236            (const_string "SI")))])
1238 ;; Stores and loads of ax to arbitrary constant address.
1239 ;; We fake an second form of instruction to force reload to load address
1240 ;; into register when rax is not available
1241 (define_insn "*movabssi_1_rex64"
1242   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1243         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1244   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1245   "@
1246    movabs{l}\t{%1, %P0|%P0, %1}
1247    mov{l}\t{%1, %a0|%a0, %1}"
1248   [(set_attr "type" "imov")
1249    (set_attr "modrm" "0,*")
1250    (set_attr "length_address" "8,0")
1251    (set_attr "length_immediate" "0,*")
1252    (set_attr "memory" "store")
1253    (set_attr "mode" "SI")])
1255 (define_insn "*movabssi_2_rex64"
1256   [(set (match_operand:SI 0 "register_operand" "=a,r")
1257         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1258   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1259   "@
1260    movabs{l}\t{%P1, %0|%0, %P1}
1261    mov{l}\t{%a1, %0|%0, %a1}"
1262   [(set_attr "type" "imov")
1263    (set_attr "modrm" "0,*")
1264    (set_attr "length_address" "8,0")
1265    (set_attr "length_immediate" "0")
1266    (set_attr "memory" "load")
1267    (set_attr "mode" "SI")])
1269 (define_insn "*swapsi"
1270   [(set (match_operand:SI 0 "register_operand" "+r")
1271         (match_operand:SI 1 "register_operand" "+r"))
1272    (set (match_dup 1)
1273         (match_dup 0))]
1274   ""
1275   "xchg{l}\t%1, %0"
1276   [(set_attr "type" "imov")
1277    (set_attr "mode" "SI")
1278    (set_attr "pent_pair" "np")
1279    (set_attr "athlon_decode" "vector")])
1281 (define_expand "movhi"
1282   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1283         (match_operand:HI 1 "general_operand" ""))]
1284   ""
1285   "ix86_expand_move (HImode, operands); DONE;")
1287 (define_insn "*pushhi2"
1288   [(set (match_operand:HI 0 "push_operand" "=X")
1289         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1290   "!TARGET_64BIT"
1291   "push{l}\t%k1"
1292   [(set_attr "type" "push")
1293    (set_attr "mode" "SI")])
1295 ;; For 64BIT abi we always round up to 8 bytes.
1296 (define_insn "*pushhi2_rex64"
1297   [(set (match_operand:HI 0 "push_operand" "=X")
1298         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1299   "TARGET_64BIT"
1300   "push{q}\t%q1"
1301   [(set_attr "type" "push")
1302    (set_attr "mode" "DI")])
1304 (define_insn "*movhi_1"
1305   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1306         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1307   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1309   switch (get_attr_type (insn))
1310     {
1311     case TYPE_IMOVX:
1312       /* movzwl is faster than movw on p2 due to partial word stalls,
1313          though not as fast as an aligned movl.  */
1314       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1315     default:
1316       if (get_attr_mode (insn) == MODE_SI)
1317         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1318       else
1319         return "mov{w}\t{%1, %0|%0, %1}";
1320     }
1322   [(set (attr "type")
1323      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1324               (const_string "imov")
1325             (and (eq_attr "alternative" "0")
1326                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1327                           (const_int 0))
1328                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1329                           (const_int 0))))
1330               (const_string "imov")
1331             (and (eq_attr "alternative" "1,2")
1332                  (match_operand:HI 1 "aligned_operand" ""))
1333               (const_string "imov")
1334             (and (ne (symbol_ref "TARGET_MOVX")
1335                      (const_int 0))
1336                  (eq_attr "alternative" "0,2"))
1337               (const_string "imovx")
1338            ]
1339            (const_string "imov")))
1340     (set (attr "mode")
1341       (cond [(eq_attr "type" "imovx")
1342                (const_string "SI")
1343              (and (eq_attr "alternative" "1,2")
1344                   (match_operand:HI 1 "aligned_operand" ""))
1345                (const_string "SI")
1346              (and (eq_attr "alternative" "0")
1347                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1348                            (const_int 0))
1349                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1350                            (const_int 0))))
1351                (const_string "SI")
1352             ]
1353             (const_string "HI")))])
1355 ;; Stores and loads of ax to arbitrary constant address.
1356 ;; We fake an second form of instruction to force reload to load address
1357 ;; into register when rax is not available
1358 (define_insn "*movabshi_1_rex64"
1359   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1360         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1361   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1362   "@
1363    movabs{w}\t{%1, %P0|%P0, %1}
1364    mov{w}\t{%1, %a0|%a0, %1}"
1365   [(set_attr "type" "imov")
1366    (set_attr "modrm" "0,*")
1367    (set_attr "length_address" "8,0")
1368    (set_attr "length_immediate" "0,*")
1369    (set_attr "memory" "store")
1370    (set_attr "mode" "HI")])
1372 (define_insn "*movabshi_2_rex64"
1373   [(set (match_operand:HI 0 "register_operand" "=a,r")
1374         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1375   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1376   "@
1377    movabs{w}\t{%P1, %0|%0, %P1}
1378    mov{w}\t{%a1, %0|%0, %a1}"
1379   [(set_attr "type" "imov")
1380    (set_attr "modrm" "0,*")
1381    (set_attr "length_address" "8,0")
1382    (set_attr "length_immediate" "0")
1383    (set_attr "memory" "load")
1384    (set_attr "mode" "HI")])
1386 (define_insn "*swaphi_1"
1387   [(set (match_operand:HI 0 "register_operand" "+r")
1388         (match_operand:HI 1 "register_operand" "+r"))
1389    (set (match_dup 1)
1390         (match_dup 0))]
1391   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1392   "xchg{l}\t%k1, %k0"
1393   [(set_attr "type" "imov")
1394    (set_attr "mode" "SI")
1395    (set_attr "pent_pair" "np")
1396    (set_attr "athlon_decode" "vector")])
1398 (define_insn "*swaphi_2"
1399   [(set (match_operand:HI 0 "register_operand" "+r")
1400         (match_operand:HI 1 "register_operand" "+r"))
1401    (set (match_dup 1)
1402         (match_dup 0))]
1403   "TARGET_PARTIAL_REG_STALL"
1404   "xchg{w}\t%1, %0"
1405   [(set_attr "type" "imov")
1406    (set_attr "mode" "HI")
1407    (set_attr "pent_pair" "np")
1408    (set_attr "athlon_decode" "vector")])
1410 (define_expand "movstricthi"
1411   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1412         (match_operand:HI 1 "general_operand" ""))]
1413   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1415   /* Don't generate memory->memory moves, go through a register */
1416   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1417     operands[1] = force_reg (HImode, operands[1]);
1420 (define_insn "*movstricthi_1"
1421   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1422         (match_operand:HI 1 "general_operand" "rn,m"))]
1423   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1424    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1425   "mov{w}\t{%1, %0|%0, %1}"
1426   [(set_attr "type" "imov")
1427    (set_attr "mode" "HI")])
1429 (define_insn "*movstricthi_xor"
1430   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1431         (match_operand:HI 1 "const0_operand" "i"))
1432    (clobber (reg:CC FLAGS_REG))]
1433   "reload_completed
1434    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1435   "xor{w}\t{%0, %0|%0, %0}"
1436   [(set_attr "type" "alu1")
1437    (set_attr "mode" "HI")
1438    (set_attr "length_immediate" "0")])
1440 (define_expand "movqi"
1441   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1442         (match_operand:QI 1 "general_operand" ""))]
1443   ""
1444   "ix86_expand_move (QImode, operands); DONE;")
1446 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1447 ;; "push a byte".  But actually we use pushl, which has the effect
1448 ;; of rounding the amount pushed up to a word.
1450 (define_insn "*pushqi2"
1451   [(set (match_operand:QI 0 "push_operand" "=X")
1452         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1453   "!TARGET_64BIT"
1454   "push{l}\t%k1"
1455   [(set_attr "type" "push")
1456    (set_attr "mode" "SI")])
1458 ;; For 64BIT abi we always round up to 8 bytes.
1459 (define_insn "*pushqi2_rex64"
1460   [(set (match_operand:QI 0 "push_operand" "=X")
1461         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1462   "TARGET_64BIT"
1463   "push{q}\t%q1"
1464   [(set_attr "type" "push")
1465    (set_attr "mode" "DI")])
1467 ;; Situation is quite tricky about when to choose full sized (SImode) move
1468 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1469 ;; partial register dependency machines (such as AMD Athlon), where QImode
1470 ;; moves issue extra dependency and for partial register stalls machines
1471 ;; that don't use QImode patterns (and QImode move cause stall on the next
1472 ;; instruction).
1474 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1475 ;; register stall machines with, where we use QImode instructions, since
1476 ;; partial register stall can be caused there.  Then we use movzx.
1477 (define_insn "*movqi_1"
1478   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1479         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1480   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1482   switch (get_attr_type (insn))
1483     {
1484     case TYPE_IMOVX:
1485       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1486       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1487     default:
1488       if (get_attr_mode (insn) == MODE_SI)
1489         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1490       else
1491         return "mov{b}\t{%1, %0|%0, %1}";
1492     }
1494   [(set (attr "type")
1495      (cond [(and (eq_attr "alternative" "5")
1496                  (not (match_operand:QI 1 "aligned_operand" "")))
1497               (const_string "imovx")
1498             (ne (symbol_ref "optimize_size") (const_int 0))
1499               (const_string "imov")
1500             (and (eq_attr "alternative" "3")
1501                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1502                           (const_int 0))
1503                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1504                           (const_int 0))))
1505               (const_string "imov")
1506             (eq_attr "alternative" "3,5")
1507               (const_string "imovx")
1508             (and (ne (symbol_ref "TARGET_MOVX")
1509                      (const_int 0))
1510                  (eq_attr "alternative" "2"))
1511               (const_string "imovx")
1512            ]
1513            (const_string "imov")))
1514    (set (attr "mode")
1515       (cond [(eq_attr "alternative" "3,4,5")
1516                (const_string "SI")
1517              (eq_attr "alternative" "6")
1518                (const_string "QI")
1519              (eq_attr "type" "imovx")
1520                (const_string "SI")
1521              (and (eq_attr "type" "imov")
1522                   (and (eq_attr "alternative" "0,1")
1523                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1524                                 (const_int 0))
1525                             (and (eq (symbol_ref "optimize_size")
1526                                      (const_int 0))
1527                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1528                                      (const_int 0))))))
1529                (const_string "SI")
1530              ;; Avoid partial register stalls when not using QImode arithmetic
1531              (and (eq_attr "type" "imov")
1532                   (and (eq_attr "alternative" "0,1")
1533                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1534                                 (const_int 0))
1535                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1536                                 (const_int 0)))))
1537                (const_string "SI")
1538            ]
1539            (const_string "QI")))])
1541 (define_expand "reload_outqi"
1542   [(parallel [(match_operand:QI 0 "" "=m")
1543               (match_operand:QI 1 "register_operand" "r")
1544               (match_operand:QI 2 "register_operand" "=&q")])]
1545   ""
1547   rtx op0, op1, op2;
1548   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1550   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1551   if (! q_regs_operand (op1, QImode))
1552     {
1553       emit_insn (gen_movqi (op2, op1));
1554       op1 = op2;
1555     }
1556   emit_insn (gen_movqi (op0, op1));
1557   DONE;
1560 (define_insn "*swapqi_1"
1561   [(set (match_operand:QI 0 "register_operand" "+r")
1562         (match_operand:QI 1 "register_operand" "+r"))
1563    (set (match_dup 1)
1564         (match_dup 0))]
1565   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1566   "xchg{l}\t%k1, %k0"
1567   [(set_attr "type" "imov")
1568    (set_attr "mode" "SI")
1569    (set_attr "pent_pair" "np")
1570    (set_attr "athlon_decode" "vector")])
1572 (define_insn "*swapqi_2"
1573   [(set (match_operand:QI 0 "register_operand" "+q")
1574         (match_operand:QI 1 "register_operand" "+q"))
1575    (set (match_dup 1)
1576         (match_dup 0))]
1577   "TARGET_PARTIAL_REG_STALL"
1578   "xchg{b}\t%1, %0"
1579   [(set_attr "type" "imov")
1580    (set_attr "mode" "QI")
1581    (set_attr "pent_pair" "np")
1582    (set_attr "athlon_decode" "vector")])
1584 (define_expand "movstrictqi"
1585   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1586         (match_operand:QI 1 "general_operand" ""))]
1587   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1589   /* Don't generate memory->memory moves, go through a register.  */
1590   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1591     operands[1] = force_reg (QImode, operands[1]);
1594 (define_insn "*movstrictqi_1"
1595   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1596         (match_operand:QI 1 "general_operand" "*qn,m"))]
1597   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1598    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1599   "mov{b}\t{%1, %0|%0, %1}"
1600   [(set_attr "type" "imov")
1601    (set_attr "mode" "QI")])
1603 (define_insn "*movstrictqi_xor"
1604   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1605         (match_operand:QI 1 "const0_operand" "i"))
1606    (clobber (reg:CC FLAGS_REG))]
1607   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1608   "xor{b}\t{%0, %0|%0, %0}"
1609   [(set_attr "type" "alu1")
1610    (set_attr "mode" "QI")
1611    (set_attr "length_immediate" "0")])
1613 (define_insn "*movsi_extv_1"
1614   [(set (match_operand:SI 0 "register_operand" "=R")
1615         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1616                          (const_int 8)
1617                          (const_int 8)))]
1618   ""
1619   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1620   [(set_attr "type" "imovx")
1621    (set_attr "mode" "SI")])
1623 (define_insn "*movhi_extv_1"
1624   [(set (match_operand:HI 0 "register_operand" "=R")
1625         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1626                          (const_int 8)
1627                          (const_int 8)))]
1628   ""
1629   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1630   [(set_attr "type" "imovx")
1631    (set_attr "mode" "SI")])
1633 (define_insn "*movqi_extv_1"
1634   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1635         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1636                          (const_int 8)
1637                          (const_int 8)))]
1638   "!TARGET_64BIT"
1640   switch (get_attr_type (insn))
1641     {
1642     case TYPE_IMOVX:
1643       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1644     default:
1645       return "mov{b}\t{%h1, %0|%0, %h1}";
1646     }
1648   [(set (attr "type")
1649      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1650                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1651                              (ne (symbol_ref "TARGET_MOVX")
1652                                  (const_int 0))))
1653         (const_string "imovx")
1654         (const_string "imov")))
1655    (set (attr "mode")
1656      (if_then_else (eq_attr "type" "imovx")
1657         (const_string "SI")
1658         (const_string "QI")))])
1660 (define_insn "*movqi_extv_1_rex64"
1661   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1662         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1663                          (const_int 8)
1664                          (const_int 8)))]
1665   "TARGET_64BIT"
1667   switch (get_attr_type (insn))
1668     {
1669     case TYPE_IMOVX:
1670       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1671     default:
1672       return "mov{b}\t{%h1, %0|%0, %h1}";
1673     }
1675   [(set (attr "type")
1676      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678                              (ne (symbol_ref "TARGET_MOVX")
1679                                  (const_int 0))))
1680         (const_string "imovx")
1681         (const_string "imov")))
1682    (set (attr "mode")
1683      (if_then_else (eq_attr "type" "imovx")
1684         (const_string "SI")
1685         (const_string "QI")))])
1687 ;; Stores and loads of ax to arbitrary constant address.
1688 ;; We fake an second form of instruction to force reload to load address
1689 ;; into register when rax is not available
1690 (define_insn "*movabsqi_1_rex64"
1691   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1692         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1693   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1694   "@
1695    movabs{b}\t{%1, %P0|%P0, %1}
1696    mov{b}\t{%1, %a0|%a0, %1}"
1697   [(set_attr "type" "imov")
1698    (set_attr "modrm" "0,*")
1699    (set_attr "length_address" "8,0")
1700    (set_attr "length_immediate" "0,*")
1701    (set_attr "memory" "store")
1702    (set_attr "mode" "QI")])
1704 (define_insn "*movabsqi_2_rex64"
1705   [(set (match_operand:QI 0 "register_operand" "=a,r")
1706         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1707   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1708   "@
1709    movabs{b}\t{%P1, %0|%0, %P1}
1710    mov{b}\t{%a1, %0|%0, %a1}"
1711   [(set_attr "type" "imov")
1712    (set_attr "modrm" "0,*")
1713    (set_attr "length_address" "8,0")
1714    (set_attr "length_immediate" "0")
1715    (set_attr "memory" "load")
1716    (set_attr "mode" "QI")])
1718 (define_insn "*movdi_extzv_1"
1719   [(set (match_operand:DI 0 "register_operand" "=R")
1720         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1721                          (const_int 8)
1722                          (const_int 8)))]
1723   "TARGET_64BIT"
1724   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1725   [(set_attr "type" "imovx")
1726    (set_attr "mode" "DI")])
1728 (define_insn "*movsi_extzv_1"
1729   [(set (match_operand:SI 0 "register_operand" "=R")
1730         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1731                          (const_int 8)
1732                          (const_int 8)))]
1733   ""
1734   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1735   [(set_attr "type" "imovx")
1736    (set_attr "mode" "SI")])
1738 (define_insn "*movqi_extzv_2"
1739   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1740         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1741                                     (const_int 8)
1742                                     (const_int 8)) 0))]
1743   "!TARGET_64BIT"
1745   switch (get_attr_type (insn))
1746     {
1747     case TYPE_IMOVX:
1748       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1749     default:
1750       return "mov{b}\t{%h1, %0|%0, %h1}";
1751     }
1753   [(set (attr "type")
1754      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1755                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1756                              (ne (symbol_ref "TARGET_MOVX")
1757                                  (const_int 0))))
1758         (const_string "imovx")
1759         (const_string "imov")))
1760    (set (attr "mode")
1761      (if_then_else (eq_attr "type" "imovx")
1762         (const_string "SI")
1763         (const_string "QI")))])
1765 (define_insn "*movqi_extzv_2_rex64"
1766   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1767         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1768                                     (const_int 8)
1769                                     (const_int 8)) 0))]
1770   "TARGET_64BIT"
1772   switch (get_attr_type (insn))
1773     {
1774     case TYPE_IMOVX:
1775       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1776     default:
1777       return "mov{b}\t{%h1, %0|%0, %h1}";
1778     }
1780   [(set (attr "type")
1781      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1782                         (ne (symbol_ref "TARGET_MOVX")
1783                             (const_int 0)))
1784         (const_string "imovx")
1785         (const_string "imov")))
1786    (set (attr "mode")
1787      (if_then_else (eq_attr "type" "imovx")
1788         (const_string "SI")
1789         (const_string "QI")))])
1791 (define_insn "movsi_insv_1"
1792   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1793                          (const_int 8)
1794                          (const_int 8))
1795         (match_operand:SI 1 "general_operand" "Qmn"))]
1796   "!TARGET_64BIT"
1797   "mov{b}\t{%b1, %h0|%h0, %b1}"
1798   [(set_attr "type" "imov")
1799    (set_attr "mode" "QI")])
1801 (define_insn "movdi_insv_1_rex64"
1802   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1803                          (const_int 8)
1804                          (const_int 8))
1805         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1806   "TARGET_64BIT"
1807   "mov{b}\t{%b1, %h0|%h0, %b1}"
1808   [(set_attr "type" "imov")
1809    (set_attr "mode" "QI")])
1811 (define_insn "*movqi_insv_2"
1812   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1813                          (const_int 8)
1814                          (const_int 8))
1815         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1816                      (const_int 8)))]
1817   ""
1818   "mov{b}\t{%h1, %h0|%h0, %h1}"
1819   [(set_attr "type" "imov")
1820    (set_attr "mode" "QI")])
1822 (define_expand "movdi"
1823   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1824         (match_operand:DI 1 "general_operand" ""))]
1825   ""
1826   "ix86_expand_move (DImode, operands); DONE;")
1828 (define_insn "*pushdi"
1829   [(set (match_operand:DI 0 "push_operand" "=<")
1830         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1831   "!TARGET_64BIT"
1832   "#")
1834 (define_insn "*pushdi2_rex64"
1835   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1836         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1837   "TARGET_64BIT"
1838   "@
1839    push{q}\t%1
1840    #"
1841   [(set_attr "type" "push,multi")
1842    (set_attr "mode" "DI")])
1844 ;; Convert impossible pushes of immediate to existing instructions.
1845 ;; First try to get scratch register and go through it.  In case this
1846 ;; fails, push sign extended lower part first and then overwrite
1847 ;; upper part by 32bit move.
1848 (define_peephole2
1849   [(match_scratch:DI 2 "r")
1850    (set (match_operand:DI 0 "push_operand" "")
1851         (match_operand:DI 1 "immediate_operand" ""))]
1852   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1853    && !x86_64_immediate_operand (operands[1], DImode)"
1854   [(set (match_dup 2) (match_dup 1))
1855    (set (match_dup 0) (match_dup 2))]
1856   "")
1858 ;; We need to define this as both peepholer and splitter for case
1859 ;; peephole2 pass is not run.
1860 ;; "&& 1" is needed to keep it from matching the previous pattern.
1861 (define_peephole2
1862   [(set (match_operand:DI 0 "push_operand" "")
1863         (match_operand:DI 1 "immediate_operand" ""))]
1864   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1865    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1866   [(set (match_dup 0) (match_dup 1))
1867    (set (match_dup 2) (match_dup 3))]
1868   "split_di (operands + 1, 1, operands + 2, operands + 3);
1869    operands[1] = gen_lowpart (DImode, operands[2]);
1870    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1871                                                     GEN_INT (4)));
1872   ")
1874 (define_split
1875   [(set (match_operand:DI 0 "push_operand" "")
1876         (match_operand:DI 1 "immediate_operand" ""))]
1877   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1878                     ? flow2_completed : reload_completed)
1879    && !symbolic_operand (operands[1], DImode)
1880    && !x86_64_immediate_operand (operands[1], DImode)"
1881   [(set (match_dup 0) (match_dup 1))
1882    (set (match_dup 2) (match_dup 3))]
1883   "split_di (operands + 1, 1, operands + 2, operands + 3);
1884    operands[1] = gen_lowpart (DImode, operands[2]);
1885    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1886                                                     GEN_INT (4)));
1887   ")
1889 (define_insn "*pushdi2_prologue_rex64"
1890   [(set (match_operand:DI 0 "push_operand" "=<")
1891         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1892    (clobber (mem:BLK (scratch)))]
1893   "TARGET_64BIT"
1894   "push{q}\t%1"
1895   [(set_attr "type" "push")
1896    (set_attr "mode" "DI")])
1898 (define_insn "*popdi1_epilogue_rex64"
1899   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1900         (mem:DI (reg:DI SP_REG)))
1901    (set (reg:DI SP_REG)
1902         (plus:DI (reg:DI SP_REG) (const_int 8)))
1903    (clobber (mem:BLK (scratch)))]
1904   "TARGET_64BIT"
1905   "pop{q}\t%0"
1906   [(set_attr "type" "pop")
1907    (set_attr "mode" "DI")])
1909 (define_insn "popdi1"
1910   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1911         (mem:DI (reg:DI SP_REG)))
1912    (set (reg:DI SP_REG)
1913         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1914   "TARGET_64BIT"
1915   "pop{q}\t%0"
1916   [(set_attr "type" "pop")
1917    (set_attr "mode" "DI")])
1919 (define_insn "*movdi_xor_rex64"
1920   [(set (match_operand:DI 0 "register_operand" "=r")
1921         (match_operand:DI 1 "const0_operand" "i"))
1922    (clobber (reg:CC FLAGS_REG))]
1923   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1924    && reload_completed"
1925   "xor{l}\t{%k0, %k0|%k0, %k0}"
1926   [(set_attr "type" "alu1")
1927    (set_attr "mode" "SI")
1928    (set_attr "length_immediate" "0")])
1930 (define_insn "*movdi_or_rex64"
1931   [(set (match_operand:DI 0 "register_operand" "=r")
1932         (match_operand:DI 1 "const_int_operand" "i"))
1933    (clobber (reg:CC FLAGS_REG))]
1934   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1935    && reload_completed
1936    && operands[1] == constm1_rtx"
1938   operands[1] = constm1_rtx;
1939   return "or{q}\t{%1, %0|%0, %1}";
1941   [(set_attr "type" "alu1")
1942    (set_attr "mode" "DI")
1943    (set_attr "length_immediate" "1")])
1945 (define_insn "*movdi_2"
1946   [(set (match_operand:DI 0 "nonimmediate_operand"
1947                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1948         (match_operand:DI 1 "general_operand"
1949                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1950   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1951   "@
1952    #
1953    #
1954    pxor\t%0, %0
1955    movq\t{%1, %0|%0, %1}
1956    movq\t{%1, %0|%0, %1}
1957    pxor\t%0, %0
1958    movq\t{%1, %0|%0, %1}
1959    movdqa\t{%1, %0|%0, %1}
1960    movq\t{%1, %0|%0, %1}
1961    xorps\t%0, %0
1962    movlps\t{%1, %0|%0, %1}
1963    movaps\t{%1, %0|%0, %1}
1964    movlps\t{%1, %0|%0, %1}"
1965   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1966    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1968 (define_split
1969   [(set (match_operand:DI 0 "push_operand" "")
1970         (match_operand:DI 1 "general_operand" ""))]
1971   "!TARGET_64BIT && reload_completed
1972    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1973   [(const_int 0)]
1974   "ix86_split_long_move (operands); DONE;")
1976 ;; %%% This multiword shite has got to go.
1977 (define_split
1978   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1979         (match_operand:DI 1 "general_operand" ""))]
1980   "!TARGET_64BIT && reload_completed
1981    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1982    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1983   [(const_int 0)]
1984   "ix86_split_long_move (operands); DONE;")
1986 (define_insn "*movdi_1_rex64"
1987   [(set (match_operand:DI 0 "nonimmediate_operand"
1988                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1989         (match_operand:DI 1 "general_operand"
1990                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1991   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1993   switch (get_attr_type (insn))
1994     {
1995     case TYPE_SSECVT:
1996       if (which_alternative == 13)
1997         return "movq2dq\t{%1, %0|%0, %1}";
1998       else
1999         return "movdq2q\t{%1, %0|%0, %1}";
2000     case TYPE_SSEMOV:
2001       if (get_attr_mode (insn) == MODE_TI)
2002           return "movdqa\t{%1, %0|%0, %1}";
2003       /* FALLTHRU */
2004     case TYPE_MMXMOV:
2005       /* Moves from and into integer register is done using movd opcode with
2006          REX prefix.  */
2007       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2008           return "movd\t{%1, %0|%0, %1}";
2009       return "movq\t{%1, %0|%0, %1}";
2010     case TYPE_SSELOG1:
2011     case TYPE_MMXADD:
2012       return "pxor\t%0, %0";
2013     case TYPE_MULTI:
2014       return "#";
2015     case TYPE_LEA:
2016       return "lea{q}\t{%a1, %0|%0, %a1}";
2017     default:
2018       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2019       if (get_attr_mode (insn) == MODE_SI)
2020         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2021       else if (which_alternative == 2)
2022         return "movabs{q}\t{%1, %0|%0, %1}";
2023       else
2024         return "mov{q}\t{%1, %0|%0, %1}";
2025     }
2027   [(set (attr "type")
2028      (cond [(eq_attr "alternative" "5")
2029               (const_string "mmxadd")
2030             (eq_attr "alternative" "6,7,8")
2031               (const_string "mmxmov")
2032             (eq_attr "alternative" "9")
2033               (const_string "sselog1")
2034             (eq_attr "alternative" "10,11,12")
2035               (const_string "ssemov")
2036             (eq_attr "alternative" "13,14")
2037               (const_string "ssecvt")
2038             (eq_attr "alternative" "4")
2039               (const_string "multi")
2040             (match_operand:DI 1 "pic_32bit_operand" "")
2041               (const_string "lea")
2042            ]
2043            (const_string "imov")))
2044    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2045    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2046    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2048 ;; Stores and loads of ax to arbitrary constant address.
2049 ;; We fake an second form of instruction to force reload to load address
2050 ;; into register when rax is not available
2051 (define_insn "*movabsdi_1_rex64"
2052   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2053         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2054   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2055   "@
2056    movabs{q}\t{%1, %P0|%P0, %1}
2057    mov{q}\t{%1, %a0|%a0, %1}"
2058   [(set_attr "type" "imov")
2059    (set_attr "modrm" "0,*")
2060    (set_attr "length_address" "8,0")
2061    (set_attr "length_immediate" "0,*")
2062    (set_attr "memory" "store")
2063    (set_attr "mode" "DI")])
2065 (define_insn "*movabsdi_2_rex64"
2066   [(set (match_operand:DI 0 "register_operand" "=a,r")
2067         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2068   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2069   "@
2070    movabs{q}\t{%P1, %0|%0, %P1}
2071    mov{q}\t{%a1, %0|%0, %a1}"
2072   [(set_attr "type" "imov")
2073    (set_attr "modrm" "0,*")
2074    (set_attr "length_address" "8,0")
2075    (set_attr "length_immediate" "0")
2076    (set_attr "memory" "load")
2077    (set_attr "mode" "DI")])
2079 ;; Convert impossible stores of immediate to existing instructions.
2080 ;; First try to get scratch register and go through it.  In case this
2081 ;; fails, move by 32bit parts.
2082 (define_peephole2
2083   [(match_scratch:DI 2 "r")
2084    (set (match_operand:DI 0 "memory_operand" "")
2085         (match_operand:DI 1 "immediate_operand" ""))]
2086   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2087    && !x86_64_immediate_operand (operands[1], DImode)"
2088   [(set (match_dup 2) (match_dup 1))
2089    (set (match_dup 0) (match_dup 2))]
2090   "")
2092 ;; We need to define this as both peepholer and splitter for case
2093 ;; peephole2 pass is not run.
2094 ;; "&& 1" is needed to keep it from matching the previous pattern.
2095 (define_peephole2
2096   [(set (match_operand:DI 0 "memory_operand" "")
2097         (match_operand:DI 1 "immediate_operand" ""))]
2098   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2099    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2100   [(set (match_dup 2) (match_dup 3))
2101    (set (match_dup 4) (match_dup 5))]
2102   "split_di (operands, 2, operands + 2, operands + 4);")
2104 (define_split
2105   [(set (match_operand:DI 0 "memory_operand" "")
2106         (match_operand:DI 1 "immediate_operand" ""))]
2107   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2108                     ? flow2_completed : reload_completed)
2109    && !symbolic_operand (operands[1], DImode)
2110    && !x86_64_immediate_operand (operands[1], DImode)"
2111   [(set (match_dup 2) (match_dup 3))
2112    (set (match_dup 4) (match_dup 5))]
2113   "split_di (operands, 2, operands + 2, operands + 4);")
2115 (define_insn "*swapdi_rex64"
2116   [(set (match_operand:DI 0 "register_operand" "+r")
2117         (match_operand:DI 1 "register_operand" "+r"))
2118    (set (match_dup 1)
2119         (match_dup 0))]
2120   "TARGET_64BIT"
2121   "xchg{q}\t%1, %0"
2122   [(set_attr "type" "imov")
2123    (set_attr "mode" "DI")
2124    (set_attr "pent_pair" "np")
2125    (set_attr "athlon_decode" "vector")])
2127 (define_expand "movti"
2128   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2129         (match_operand:TI 1 "nonimmediate_operand" ""))]
2130   "TARGET_SSE || TARGET_64BIT"
2132   if (TARGET_64BIT)
2133     ix86_expand_move (TImode, operands);
2134   else
2135     ix86_expand_vector_move (TImode, operands);
2136   DONE;
2139 (define_insn "*movti_internal"
2140   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2141         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2142   "TARGET_SSE && !TARGET_64BIT
2143    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2145   switch (which_alternative)
2146     {
2147     case 0:
2148       if (get_attr_mode (insn) == MODE_V4SF)
2149         return "xorps\t%0, %0";
2150       else
2151         return "pxor\t%0, %0";
2152     case 1:
2153     case 2:
2154       if (get_attr_mode (insn) == MODE_V4SF)
2155         return "movaps\t{%1, %0|%0, %1}";
2156       else
2157         return "movdqa\t{%1, %0|%0, %1}";
2158     default:
2159       gcc_unreachable ();
2160     }
2162   [(set_attr "type" "sselog1,ssemov,ssemov")
2163    (set (attr "mode")
2164         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2165                     (ne (symbol_ref "optimize_size") (const_int 0)))
2166                  (const_string "V4SF")
2167                (and (eq_attr "alternative" "2")
2168                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2169                         (const_int 0)))
2170                  (const_string "V4SF")]
2171               (const_string "TI")))])
2173 (define_insn "*movti_rex64"
2174   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2175         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2176   "TARGET_64BIT
2177    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2179   switch (which_alternative)
2180     {
2181     case 0:
2182     case 1:
2183       return "#";
2184     case 2:
2185       if (get_attr_mode (insn) == MODE_V4SF)
2186         return "xorps\t%0, %0";
2187       else
2188         return "pxor\t%0, %0";
2189     case 3:
2190     case 4:
2191       if (get_attr_mode (insn) == MODE_V4SF)
2192         return "movaps\t{%1, %0|%0, %1}";
2193       else
2194         return "movdqa\t{%1, %0|%0, %1}";
2195     default:
2196       gcc_unreachable ();
2197     }
2199   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2200    (set (attr "mode")
2201         (cond [(eq_attr "alternative" "2,3")
2202                  (if_then_else
2203                    (ne (symbol_ref "optimize_size")
2204                        (const_int 0))
2205                    (const_string "V4SF")
2206                    (const_string "TI"))
2207                (eq_attr "alternative" "4")
2208                  (if_then_else
2209                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2210                             (const_int 0))
2211                         (ne (symbol_ref "optimize_size")
2212                             (const_int 0)))
2213                    (const_string "V4SF")
2214                    (const_string "TI"))]
2215                (const_string "DI")))])
2217 (define_split
2218   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2219         (match_operand:TI 1 "general_operand" ""))]
2220   "reload_completed && !SSE_REG_P (operands[0])
2221    && !SSE_REG_P (operands[1])"
2222   [(const_int 0)]
2223   "ix86_split_long_move (operands); DONE;")
2225 (define_expand "movsf"
2226   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2227         (match_operand:SF 1 "general_operand" ""))]
2228   ""
2229   "ix86_expand_move (SFmode, operands); DONE;")
2231 (define_insn "*pushsf"
2232   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2233         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2234   "!TARGET_64BIT"
2236   /* Anything else should be already split before reg-stack.  */
2237   gcc_assert (which_alternative == 1);
2238   return "push{l}\t%1";
2240   [(set_attr "type" "multi,push,multi")
2241    (set_attr "unit" "i387,*,*")
2242    (set_attr "mode" "SF,SI,SF")])
2244 (define_insn "*pushsf_rex64"
2245   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2246         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2247   "TARGET_64BIT"
2249   /* Anything else should be already split before reg-stack.  */
2250   gcc_assert (which_alternative == 1);
2251   return "push{q}\t%q1";
2253   [(set_attr "type" "multi,push,multi")
2254    (set_attr "unit" "i387,*,*")
2255    (set_attr "mode" "SF,DI,SF")])
2257 (define_split
2258   [(set (match_operand:SF 0 "push_operand" "")
2259         (match_operand:SF 1 "memory_operand" ""))]
2260   "reload_completed
2261    && GET_CODE (operands[1]) == MEM
2262    && constant_pool_reference_p (operands[1])"
2263   [(set (match_dup 0)
2264         (match_dup 1))]
2265   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2268 ;; %%% Kill this when call knows how to work this out.
2269 (define_split
2270   [(set (match_operand:SF 0 "push_operand" "")
2271         (match_operand:SF 1 "any_fp_register_operand" ""))]
2272   "!TARGET_64BIT"
2273   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2274    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2276 (define_split
2277   [(set (match_operand:SF 0 "push_operand" "")
2278         (match_operand:SF 1 "any_fp_register_operand" ""))]
2279   "TARGET_64BIT"
2280   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2281    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2283 (define_insn "*movsf_1"
2284   [(set (match_operand:SF 0 "nonimmediate_operand"
2285           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2286         (match_operand:SF 1 "general_operand"
2287           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2288   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2289    && (reload_in_progress || reload_completed
2290        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2291        || GET_CODE (operands[1]) != CONST_DOUBLE
2292        || memory_operand (operands[0], SFmode))" 
2294   switch (which_alternative)
2295     {
2296     case 0:
2297       return output_387_reg_move (insn, operands);
2299     case 1:
2300       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2301         return "fstp%z0\t%y0";
2302       else
2303         return "fst%z0\t%y0";
2305     case 2:
2306       return standard_80387_constant_opcode (operands[1]);
2308     case 3:
2309     case 4:
2310       return "mov{l}\t{%1, %0|%0, %1}";
2311     case 5:
2312       if (get_attr_mode (insn) == MODE_TI)
2313         return "pxor\t%0, %0";
2314       else
2315         return "xorps\t%0, %0";
2316     case 6:
2317       if (get_attr_mode (insn) == MODE_V4SF)
2318         return "movaps\t{%1, %0|%0, %1}";
2319       else
2320         return "movss\t{%1, %0|%0, %1}";
2321     case 7:
2322     case 8:
2323       return "movss\t{%1, %0|%0, %1}";
2325     case 9:
2326     case 10:
2327       return "movd\t{%1, %0|%0, %1}";
2329     case 11:
2330       return "movq\t{%1, %0|%0, %1}";
2332     default:
2333       gcc_unreachable ();
2334     }
2336   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2337    (set (attr "mode")
2338         (cond [(eq_attr "alternative" "3,4,9,10")
2339                  (const_string "SI")
2340                (eq_attr "alternative" "5")
2341                  (if_then_else
2342                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2343                                  (const_int 0))
2344                              (ne (symbol_ref "TARGET_SSE2")
2345                                  (const_int 0)))
2346                         (eq (symbol_ref "optimize_size")
2347                             (const_int 0)))
2348                    (const_string "TI")
2349                    (const_string "V4SF"))
2350                /* For architectures resolving dependencies on
2351                   whole SSE registers use APS move to break dependency
2352                   chains, otherwise use short move to avoid extra work. 
2354                   Do the same for architectures resolving dependencies on
2355                   the parts.  While in DF mode it is better to always handle
2356                   just register parts, the SF mode is different due to lack
2357                   of instructions to load just part of the register.  It is
2358                   better to maintain the whole registers in single format
2359                   to avoid problems on using packed logical operations.  */
2360                (eq_attr "alternative" "6")
2361                  (if_then_else
2362                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2363                             (const_int 0))
2364                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2365                             (const_int 0)))
2366                    (const_string "V4SF")
2367                    (const_string "SF"))
2368                (eq_attr "alternative" "11")
2369                  (const_string "DI")]
2370                (const_string "SF")))])
2372 (define_insn "*swapsf"
2373   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2374         (match_operand:SF 1 "fp_register_operand" "+f"))
2375    (set (match_dup 1)
2376         (match_dup 0))]
2377   "reload_completed || TARGET_80387"
2379   if (STACK_TOP_P (operands[0]))
2380     return "fxch\t%1";
2381   else
2382     return "fxch\t%0";
2384   [(set_attr "type" "fxch")
2385    (set_attr "mode" "SF")])
2387 (define_expand "movdf"
2388   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2389         (match_operand:DF 1 "general_operand" ""))]
2390   ""
2391   "ix86_expand_move (DFmode, operands); DONE;")
2393 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2394 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2395 ;; On the average, pushdf using integers can be still shorter.  Allow this
2396 ;; pattern for optimize_size too.
2398 (define_insn "*pushdf_nointeger"
2399   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2400         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2401   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2403   /* This insn should be already split before reg-stack.  */
2404   gcc_unreachable ();
2406   [(set_attr "type" "multi")
2407    (set_attr "unit" "i387,*,*,*")
2408    (set_attr "mode" "DF,SI,SI,DF")])
2410 (define_insn "*pushdf_integer"
2411   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2412         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2413   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2415   /* This insn should be already split before reg-stack.  */
2416   gcc_unreachable ();
2418   [(set_attr "type" "multi")
2419    (set_attr "unit" "i387,*,*")
2420    (set_attr "mode" "DF,SI,DF")])
2422 ;; %%% Kill this when call knows how to work this out.
2423 (define_split
2424   [(set (match_operand:DF 0 "push_operand" "")
2425         (match_operand:DF 1 "any_fp_register_operand" ""))]
2426   "!TARGET_64BIT && reload_completed"
2427   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2428    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2429   "")
2431 (define_split
2432   [(set (match_operand:DF 0 "push_operand" "")
2433         (match_operand:DF 1 "any_fp_register_operand" ""))]
2434   "TARGET_64BIT && reload_completed"
2435   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2436    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2437   "")
2439 (define_split
2440   [(set (match_operand:DF 0 "push_operand" "")
2441         (match_operand:DF 1 "general_operand" ""))]
2442   "reload_completed"
2443   [(const_int 0)]
2444   "ix86_split_long_move (operands); DONE;")
2446 ;; Moving is usually shorter when only FP registers are used. This separate
2447 ;; movdf pattern avoids the use of integer registers for FP operations
2448 ;; when optimizing for size.
2450 (define_insn "*movdf_nointeger"
2451   [(set (match_operand:DF 0 "nonimmediate_operand"
2452                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2453         (match_operand:DF 1 "general_operand"
2454                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2455   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2456    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2457    && (reload_in_progress || reload_completed
2458        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2459        || GET_CODE (operands[1]) != CONST_DOUBLE
2460        || memory_operand (operands[0], DFmode))" 
2462   switch (which_alternative)
2463     {
2464     case 0:
2465       return output_387_reg_move (insn, operands);
2467     case 1:
2468       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2469         return "fstp%z0\t%y0";
2470       else
2471         return "fst%z0\t%y0";
2473     case 2:
2474       return standard_80387_constant_opcode (operands[1]);
2476     case 3:
2477     case 4:
2478       return "#";
2479     case 5:
2480       switch (get_attr_mode (insn))
2481         {
2482         case MODE_V4SF:
2483           return "xorps\t%0, %0";
2484         case MODE_V2DF:
2485           return "xorpd\t%0, %0";
2486         case MODE_TI:
2487           return "pxor\t%0, %0";
2488         default:
2489           gcc_unreachable ();
2490         }
2491     case 6:
2492     case 7:
2493     case 8:
2494       switch (get_attr_mode (insn))
2495         {
2496         case MODE_V4SF:
2497           return "movaps\t{%1, %0|%0, %1}";
2498         case MODE_V2DF:
2499           return "movapd\t{%1, %0|%0, %1}";
2500         case MODE_TI:
2501           return "movdqa\t{%1, %0|%0, %1}";
2502         case MODE_DI:
2503           return "movq\t{%1, %0|%0, %1}";
2504         case MODE_DF:
2505           return "movsd\t{%1, %0|%0, %1}";
2506         case MODE_V1DF:
2507           return "movlpd\t{%1, %0|%0, %1}";
2508         case MODE_V2SF:
2509           return "movlps\t{%1, %0|%0, %1}";
2510         default:
2511           gcc_unreachable ();
2512         }
2514     default:
2515       gcc_unreachable ();
2516     }
2518   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2519    (set (attr "mode")
2520         (cond [(eq_attr "alternative" "0,1,2")
2521                  (const_string "DF")
2522                (eq_attr "alternative" "3,4")
2523                  (const_string "SI")
2525                /* For SSE1, we have many fewer alternatives.  */
2526                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2527                  (cond [(eq_attr "alternative" "5,6")
2528                           (const_string "V4SF")
2529                        ]
2530                    (const_string "V2SF"))
2532                /* xorps is one byte shorter.  */
2533                (eq_attr "alternative" "5")
2534                  (cond [(ne (symbol_ref "optimize_size")
2535                             (const_int 0))
2536                           (const_string "V4SF")
2537                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2538                             (const_int 0))
2539                           (const_string "TI")
2540                        ]
2541                        (const_string "V2DF"))
2543                /* For architectures resolving dependencies on
2544                   whole SSE registers use APD move to break dependency
2545                   chains, otherwise use short move to avoid extra work.
2547                   movaps encodes one byte shorter.  */
2548                (eq_attr "alternative" "6")
2549                  (cond
2550                    [(ne (symbol_ref "optimize_size")
2551                         (const_int 0))
2552                       (const_string "V4SF")
2553                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2554                         (const_int 0))
2555                       (const_string "V2DF")
2556                    ]
2557                    (const_string "DF"))
2558                /* For architectures resolving dependencies on register
2559                   parts we may avoid extra work to zero out upper part
2560                   of register.  */
2561                (eq_attr "alternative" "7")
2562                  (if_then_else
2563                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2564                        (const_int 0))
2565                    (const_string "V1DF")
2566                    (const_string "DF"))
2567               ]
2568               (const_string "DF")))])
2570 (define_insn "*movdf_integer"
2571   [(set (match_operand:DF 0 "nonimmediate_operand"
2572                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2573         (match_operand:DF 1 "general_operand"
2574                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2575   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2576    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2577    && (reload_in_progress || reload_completed
2578        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2579        || GET_CODE (operands[1]) != CONST_DOUBLE
2580        || memory_operand (operands[0], DFmode))" 
2582   switch (which_alternative)
2583     {
2584     case 0:
2585       return output_387_reg_move (insn, operands);
2587     case 1:
2588       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2589         return "fstp%z0\t%y0";
2590       else
2591         return "fst%z0\t%y0";
2593     case 2:
2594       return standard_80387_constant_opcode (operands[1]);
2596     case 3:
2597     case 4:
2598       return "#";
2600     case 5:
2601       switch (get_attr_mode (insn))
2602         {
2603         case MODE_V4SF:
2604           return "xorps\t%0, %0";
2605         case MODE_V2DF:
2606           return "xorpd\t%0, %0";
2607         case MODE_TI:
2608           return "pxor\t%0, %0";
2609         default:
2610           gcc_unreachable ();
2611         }
2612     case 6:
2613     case 7:
2614     case 8:
2615       switch (get_attr_mode (insn))
2616         {
2617         case MODE_V4SF:
2618           return "movaps\t{%1, %0|%0, %1}";
2619         case MODE_V2DF:
2620           return "movapd\t{%1, %0|%0, %1}";
2621         case MODE_TI:
2622           return "movdqa\t{%1, %0|%0, %1}";
2623         case MODE_DI:
2624           return "movq\t{%1, %0|%0, %1}";
2625         case MODE_DF:
2626           return "movsd\t{%1, %0|%0, %1}";
2627         case MODE_V1DF:
2628           return "movlpd\t{%1, %0|%0, %1}";
2629         case MODE_V2SF:
2630           return "movlps\t{%1, %0|%0, %1}";
2631         default:
2632           gcc_unreachable ();
2633         }
2635     default:
2636       gcc_unreachable();
2637     }
2639   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2640    (set (attr "mode")
2641         (cond [(eq_attr "alternative" "0,1,2")
2642                  (const_string "DF")
2643                (eq_attr "alternative" "3,4")
2644                  (const_string "SI")
2646                /* For SSE1, we have many fewer alternatives.  */
2647                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2648                  (cond [(eq_attr "alternative" "5,6")
2649                           (const_string "V4SF")
2650                        ]
2651                    (const_string "V2SF"))
2653                /* xorps is one byte shorter.  */
2654                (eq_attr "alternative" "5")
2655                  (cond [(ne (symbol_ref "optimize_size")
2656                             (const_int 0))
2657                           (const_string "V4SF")
2658                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2659                             (const_int 0))
2660                           (const_string "TI")
2661                        ]
2662                        (const_string "V2DF"))
2664                /* For architectures resolving dependencies on
2665                   whole SSE registers use APD move to break dependency
2666                   chains, otherwise use short move to avoid extra work.
2668                   movaps encodes one byte shorter.  */
2669                (eq_attr "alternative" "6")
2670                  (cond
2671                    [(ne (symbol_ref "optimize_size")
2672                         (const_int 0))
2673                       (const_string "V4SF")
2674                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2675                         (const_int 0))
2676                       (const_string "V2DF")
2677                    ]
2678                    (const_string "DF"))
2679                /* For architectures resolving dependencies on register
2680                   parts we may avoid extra work to zero out upper part
2681                   of register.  */
2682                (eq_attr "alternative" "7")
2683                  (if_then_else
2684                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2685                        (const_int 0))
2686                    (const_string "V1DF")
2687                    (const_string "DF"))
2688               ]
2689               (const_string "DF")))])
2691 (define_split
2692   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2693         (match_operand:DF 1 "general_operand" ""))]
2694   "reload_completed
2695    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2696    && ! (ANY_FP_REG_P (operands[0]) || 
2697          (GET_CODE (operands[0]) == SUBREG
2698           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2699    && ! (ANY_FP_REG_P (operands[1]) || 
2700          (GET_CODE (operands[1]) == SUBREG
2701           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2702   [(const_int 0)]
2703   "ix86_split_long_move (operands); DONE;")
2705 (define_insn "*swapdf"
2706   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2707         (match_operand:DF 1 "fp_register_operand" "+f"))
2708    (set (match_dup 1)
2709         (match_dup 0))]
2710   "reload_completed || TARGET_80387"
2712   if (STACK_TOP_P (operands[0]))
2713     return "fxch\t%1";
2714   else
2715     return "fxch\t%0";
2717   [(set_attr "type" "fxch")
2718    (set_attr "mode" "DF")])
2720 (define_expand "movxf"
2721   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2722         (match_operand:XF 1 "general_operand" ""))]
2723   ""
2724   "ix86_expand_move (XFmode, operands); DONE;")
2726 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2727 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2728 ;; Pushing using integer instructions is longer except for constants
2729 ;; and direct memory references.
2730 ;; (assuming that any given constant is pushed only once, but this ought to be
2731 ;;  handled elsewhere).
2733 (define_insn "*pushxf_nointeger"
2734   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2735         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2736   "optimize_size"
2738   /* This insn should be already split before reg-stack.  */
2739   gcc_unreachable ();
2741   [(set_attr "type" "multi")
2742    (set_attr "unit" "i387,*,*")
2743    (set_attr "mode" "XF,SI,SI")])
2745 (define_insn "*pushxf_integer"
2746   [(set (match_operand:XF 0 "push_operand" "=<,<")
2747         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2748   "!optimize_size"
2750   /* This insn should be already split before reg-stack.  */
2751   gcc_unreachable ();
2753   [(set_attr "type" "multi")
2754    (set_attr "unit" "i387,*")
2755    (set_attr "mode" "XF,SI")])
2757 (define_split
2758   [(set (match_operand 0 "push_operand" "")
2759         (match_operand 1 "general_operand" ""))]
2760   "reload_completed
2761    && (GET_MODE (operands[0]) == XFmode
2762        || GET_MODE (operands[0]) == DFmode)
2763    && !ANY_FP_REG_P (operands[1])"
2764   [(const_int 0)]
2765   "ix86_split_long_move (operands); DONE;")
2767 (define_split
2768   [(set (match_operand:XF 0 "push_operand" "")
2769         (match_operand:XF 1 "any_fp_register_operand" ""))]
2770   "!TARGET_64BIT"
2771   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2772    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2773   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2775 (define_split
2776   [(set (match_operand:XF 0 "push_operand" "")
2777         (match_operand:XF 1 "any_fp_register_operand" ""))]
2778   "TARGET_64BIT"
2779   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2780    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2781   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2783 ;; Do not use integer registers when optimizing for size
2784 (define_insn "*movxf_nointeger"
2785   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2786         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2787   "optimize_size
2788    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2789    && (reload_in_progress || reload_completed
2790        || GET_CODE (operands[1]) != CONST_DOUBLE
2791        || memory_operand (operands[0], XFmode))" 
2793   switch (which_alternative)
2794     {
2795     case 0:
2796       return output_387_reg_move (insn, operands);
2798     case 1:
2799       /* There is no non-popping store to memory for XFmode.  So if
2800          we need one, follow the store with a load.  */
2801       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2802         return "fstp%z0\t%y0\;fld%z0\t%y0";
2803       else
2804         return "fstp%z0\t%y0";
2806     case 2:
2807       return standard_80387_constant_opcode (operands[1]);
2809     case 3: case 4:
2810       return "#";
2811     default:
2812       gcc_unreachable ();
2813     }
2815   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2816    (set_attr "mode" "XF,XF,XF,SI,SI")])
2818 (define_insn "*movxf_integer"
2819   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2820         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2821   "!optimize_size
2822    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2823    && (reload_in_progress || reload_completed
2824        || GET_CODE (operands[1]) != CONST_DOUBLE
2825        || memory_operand (operands[0], XFmode))" 
2827   switch (which_alternative)
2828     {
2829     case 0:
2830       return output_387_reg_move (insn, operands);
2832     case 1:
2833       /* There is no non-popping store to memory for XFmode.  So if
2834          we need one, follow the store with a load.  */
2835       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2836         return "fstp%z0\t%y0\;fld%z0\t%y0";
2837       else
2838         return "fstp%z0\t%y0";
2840     case 2:
2841       return standard_80387_constant_opcode (operands[1]);
2843     case 3: case 4:
2844       return "#";
2846     default:
2847       gcc_unreachable ();
2848     }
2850   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2851    (set_attr "mode" "XF,XF,XF,SI,SI")])
2853 (define_split
2854   [(set (match_operand 0 "nonimmediate_operand" "")
2855         (match_operand 1 "general_operand" ""))]
2856   "reload_completed
2857    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2858    && GET_MODE (operands[0]) == XFmode
2859    && ! (ANY_FP_REG_P (operands[0]) || 
2860          (GET_CODE (operands[0]) == SUBREG
2861           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2862    && ! (ANY_FP_REG_P (operands[1]) || 
2863          (GET_CODE (operands[1]) == SUBREG
2864           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2865   [(const_int 0)]
2866   "ix86_split_long_move (operands); DONE;")
2868 (define_split
2869   [(set (match_operand 0 "register_operand" "")
2870         (match_operand 1 "memory_operand" ""))]
2871   "reload_completed
2872    && GET_CODE (operands[1]) == MEM
2873    && (GET_MODE (operands[0]) == XFmode
2874        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2875    && constant_pool_reference_p (operands[1])"
2876   [(set (match_dup 0) (match_dup 1))]
2878   rtx c = avoid_constant_pool_reference (operands[1]);
2879   rtx r = operands[0];
2881   if (GET_CODE (r) == SUBREG)
2882     r = SUBREG_REG (r);
2884   if (SSE_REG_P (r))
2885     {
2886       if (!standard_sse_constant_p (c))
2887         FAIL;
2888     }
2889   else if (FP_REG_P (r))
2890     {
2891       if (!standard_80387_constant_p (c))
2892         FAIL;
2893     }
2894   else if (MMX_REG_P (r))
2895     FAIL;
2897   operands[1] = c;
2900 (define_insn "swapxf"
2901   [(set (match_operand:XF 0 "register_operand" "+f")
2902         (match_operand:XF 1 "register_operand" "+f"))
2903    (set (match_dup 1)
2904         (match_dup 0))]
2905   "TARGET_80387"
2907   if (STACK_TOP_P (operands[0]))
2908     return "fxch\t%1";
2909   else
2910     return "fxch\t%0";
2912   [(set_attr "type" "fxch")
2913    (set_attr "mode" "XF")])
2915 (define_expand "movtf"
2916   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2917         (match_operand:TF 1 "nonimmediate_operand" ""))]
2918   "TARGET_64BIT"
2920   ix86_expand_move (TFmode, operands);
2921   DONE;
2924 (define_insn "*movtf_internal"
2925   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2926         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2927   "TARGET_64BIT
2928    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2930   switch (which_alternative)
2931     {
2932     case 0:
2933     case 1:
2934       return "#";
2935     case 2:
2936       if (get_attr_mode (insn) == MODE_V4SF)
2937         return "xorps\t%0, %0";
2938       else
2939         return "pxor\t%0, %0";
2940     case 3:
2941     case 4:
2942       if (get_attr_mode (insn) == MODE_V4SF)
2943         return "movaps\t{%1, %0|%0, %1}";
2944       else
2945         return "movdqa\t{%1, %0|%0, %1}";
2946     default:
2947       gcc_unreachable ();
2948     }
2950   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2951    (set (attr "mode")
2952         (cond [(eq_attr "alternative" "2,3")
2953                  (if_then_else
2954                    (ne (symbol_ref "optimize_size")
2955                        (const_int 0))
2956                    (const_string "V4SF")
2957                    (const_string "TI"))
2958                (eq_attr "alternative" "4")
2959                  (if_then_else
2960                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2961                             (const_int 0))
2962                         (ne (symbol_ref "optimize_size")
2963                             (const_int 0)))
2964                    (const_string "V4SF")
2965                    (const_string "TI"))]
2966                (const_string "DI")))])
2968 (define_split
2969   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2970         (match_operand:TF 1 "general_operand" ""))]
2971   "reload_completed && !SSE_REG_P (operands[0])
2972    && !SSE_REG_P (operands[1])"
2973   [(const_int 0)]
2974   "ix86_split_long_move (operands); DONE;")
2976 ;; Zero extension instructions
2978 (define_expand "zero_extendhisi2"
2979   [(set (match_operand:SI 0 "register_operand" "")
2980      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2981   ""
2983   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2984     {
2985       operands[1] = force_reg (HImode, operands[1]);
2986       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2987       DONE;
2988     }
2991 (define_insn "zero_extendhisi2_and"
2992   [(set (match_operand:SI 0 "register_operand" "=r")
2993      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2994    (clobber (reg:CC FLAGS_REG))]
2995   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2996   "#"
2997   [(set_attr "type" "alu1")
2998    (set_attr "mode" "SI")])
3000 (define_split
3001   [(set (match_operand:SI 0 "register_operand" "")
3002         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3003    (clobber (reg:CC FLAGS_REG))]
3004   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3005   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3006               (clobber (reg:CC FLAGS_REG))])]
3007   "")
3009 (define_insn "*zero_extendhisi2_movzwl"
3010   [(set (match_operand:SI 0 "register_operand" "=r")
3011      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3012   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3013   "movz{wl|x}\t{%1, %0|%0, %1}"
3014   [(set_attr "type" "imovx")
3015    (set_attr "mode" "SI")])
3017 (define_expand "zero_extendqihi2"
3018   [(parallel
3019     [(set (match_operand:HI 0 "register_operand" "")
3020        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3021      (clobber (reg:CC FLAGS_REG))])]
3022   ""
3023   "")
3025 (define_insn "*zero_extendqihi2_and"
3026   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3027      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3028    (clobber (reg:CC FLAGS_REG))]
3029   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3030   "#"
3031   [(set_attr "type" "alu1")
3032    (set_attr "mode" "HI")])
3034 (define_insn "*zero_extendqihi2_movzbw_and"
3035   [(set (match_operand:HI 0 "register_operand" "=r,r")
3036      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3037    (clobber (reg:CC FLAGS_REG))]
3038   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3039   "#"
3040   [(set_attr "type" "imovx,alu1")
3041    (set_attr "mode" "HI")])
3043 ; zero extend to SImode here to avoid partial register stalls
3044 (define_insn "*zero_extendqihi2_movzbl"
3045   [(set (match_operand:HI 0 "register_operand" "=r")
3046      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3047   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3048   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3049   [(set_attr "type" "imovx")
3050    (set_attr "mode" "SI")])
3052 ;; For the movzbw case strip only the clobber
3053 (define_split
3054   [(set (match_operand:HI 0 "register_operand" "")
3055         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3056    (clobber (reg:CC FLAGS_REG))]
3057   "reload_completed 
3058    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3059    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3060   [(set (match_operand:HI 0 "register_operand" "")
3061         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3063 ;; When source and destination does not overlap, clear destination
3064 ;; first and then do the movb
3065 (define_split
3066   [(set (match_operand:HI 0 "register_operand" "")
3067         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3068    (clobber (reg:CC FLAGS_REG))]
3069   "reload_completed
3070    && ANY_QI_REG_P (operands[0])
3071    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3072    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3073   [(set (match_dup 0) (const_int 0))
3074    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3075   "operands[2] = gen_lowpart (QImode, operands[0]);")
3077 ;; Rest is handled by single and.
3078 (define_split
3079   [(set (match_operand:HI 0 "register_operand" "")
3080         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3081    (clobber (reg:CC FLAGS_REG))]
3082   "reload_completed
3083    && true_regnum (operands[0]) == true_regnum (operands[1])"
3084   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3085               (clobber (reg:CC FLAGS_REG))])]
3086   "")
3088 (define_expand "zero_extendqisi2"
3089   [(parallel
3090     [(set (match_operand:SI 0 "register_operand" "")
3091        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3092      (clobber (reg:CC FLAGS_REG))])]
3093   ""
3094   "")
3096 (define_insn "*zero_extendqisi2_and"
3097   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3098      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3099    (clobber (reg:CC FLAGS_REG))]
3100   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3101   "#"
3102   [(set_attr "type" "alu1")
3103    (set_attr "mode" "SI")])
3105 (define_insn "*zero_extendqisi2_movzbw_and"
3106   [(set (match_operand:SI 0 "register_operand" "=r,r")
3107      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3108    (clobber (reg:CC FLAGS_REG))]
3109   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3110   "#"
3111   [(set_attr "type" "imovx,alu1")
3112    (set_attr "mode" "SI")])
3114 (define_insn "*zero_extendqisi2_movzbw"
3115   [(set (match_operand:SI 0 "register_operand" "=r")
3116      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3117   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3118   "movz{bl|x}\t{%1, %0|%0, %1}"
3119   [(set_attr "type" "imovx")
3120    (set_attr "mode" "SI")])
3122 ;; For the movzbl case strip only the clobber
3123 (define_split
3124   [(set (match_operand:SI 0 "register_operand" "")
3125         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3126    (clobber (reg:CC FLAGS_REG))]
3127   "reload_completed 
3128    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3129    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3130   [(set (match_dup 0)
3131         (zero_extend:SI (match_dup 1)))])
3133 ;; When source and destination does not overlap, clear destination
3134 ;; first and then do the movb
3135 (define_split
3136   [(set (match_operand:SI 0 "register_operand" "")
3137         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3138    (clobber (reg:CC FLAGS_REG))]
3139   "reload_completed
3140    && ANY_QI_REG_P (operands[0])
3141    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3142    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3143    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3144   [(set (match_dup 0) (const_int 0))
3145    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3146   "operands[2] = gen_lowpart (QImode, operands[0]);")
3148 ;; Rest is handled by single and.
3149 (define_split
3150   [(set (match_operand:SI 0 "register_operand" "")
3151         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3152    (clobber (reg:CC FLAGS_REG))]
3153   "reload_completed
3154    && true_regnum (operands[0]) == true_regnum (operands[1])"
3155   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3156               (clobber (reg:CC FLAGS_REG))])]
3157   "")
3159 ;; %%% Kill me once multi-word ops are sane.
3160 (define_expand "zero_extendsidi2"
3161   [(set (match_operand:DI 0 "register_operand" "=r")
3162      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3163   ""
3164   "if (!TARGET_64BIT)
3165      {
3166        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3167        DONE;
3168      }
3169   ")
3171 (define_insn "zero_extendsidi2_32"
3172   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3173         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3174    (clobber (reg:CC FLAGS_REG))]
3175   "!TARGET_64BIT"
3176   "@
3177    #
3178    #
3179    #
3180    movd\t{%1, %0|%0, %1}
3181    movd\t{%1, %0|%0, %1}"
3182   [(set_attr "mode" "SI,SI,SI,DI,TI")
3183    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3185 (define_insn "zero_extendsidi2_rex64"
3186   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3187      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3188   "TARGET_64BIT"
3189   "@
3190    mov\t{%k1, %k0|%k0, %k1}
3191    #
3192    movd\t{%1, %0|%0, %1}
3193    movd\t{%1, %0|%0, %1}"
3194   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3195    (set_attr "mode" "SI,DI,SI,SI")])
3197 (define_split
3198   [(set (match_operand:DI 0 "memory_operand" "")
3199      (zero_extend:DI (match_dup 0)))]
3200   "TARGET_64BIT"
3201   [(set (match_dup 4) (const_int 0))]
3202   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3204 (define_split 
3205   [(set (match_operand:DI 0 "register_operand" "")
3206         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3207    (clobber (reg:CC FLAGS_REG))]
3208   "!TARGET_64BIT && reload_completed
3209    && true_regnum (operands[0]) == true_regnum (operands[1])"
3210   [(set (match_dup 4) (const_int 0))]
3211   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3213 (define_split 
3214   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3215         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3216    (clobber (reg:CC FLAGS_REG))]
3217   "!TARGET_64BIT && reload_completed
3218    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3219   [(set (match_dup 3) (match_dup 1))
3220    (set (match_dup 4) (const_int 0))]
3221   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3223 (define_insn "zero_extendhidi2"
3224   [(set (match_operand:DI 0 "register_operand" "=r")
3225      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3226   "TARGET_64BIT"
3227   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3228   [(set_attr "type" "imovx")
3229    (set_attr "mode" "DI")])
3231 (define_insn "zero_extendqidi2"
3232   [(set (match_operand:DI 0 "register_operand" "=r")
3233      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3234   "TARGET_64BIT"
3235   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3236   [(set_attr "type" "imovx")
3237    (set_attr "mode" "DI")])
3239 ;; Sign extension instructions
3241 (define_expand "extendsidi2"
3242   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3243                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3244               (clobber (reg:CC FLAGS_REG))
3245               (clobber (match_scratch:SI 2 ""))])]
3246   ""
3248   if (TARGET_64BIT)
3249     {
3250       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3251       DONE;
3252     }
3255 (define_insn "*extendsidi2_1"
3256   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3257         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3258    (clobber (reg:CC FLAGS_REG))
3259    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3260   "!TARGET_64BIT"
3261   "#")
3263 (define_insn "extendsidi2_rex64"
3264   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3265         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3266   "TARGET_64BIT"
3267   "@
3268    {cltq|cdqe}
3269    movs{lq|x}\t{%1,%0|%0, %1}"
3270   [(set_attr "type" "imovx")
3271    (set_attr "mode" "DI")
3272    (set_attr "prefix_0f" "0")
3273    (set_attr "modrm" "0,1")])
3275 (define_insn "extendhidi2"
3276   [(set (match_operand:DI 0 "register_operand" "=r")
3277         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3278   "TARGET_64BIT"
3279   "movs{wq|x}\t{%1,%0|%0, %1}"
3280   [(set_attr "type" "imovx")
3281    (set_attr "mode" "DI")])
3283 (define_insn "extendqidi2"
3284   [(set (match_operand:DI 0 "register_operand" "=r")
3285         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3286   "TARGET_64BIT"
3287   "movs{bq|x}\t{%1,%0|%0, %1}"
3288    [(set_attr "type" "imovx")
3289     (set_attr "mode" "DI")])
3291 ;; Extend to memory case when source register does die.
3292 (define_split 
3293   [(set (match_operand:DI 0 "memory_operand" "")
3294         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3295    (clobber (reg:CC FLAGS_REG))
3296    (clobber (match_operand:SI 2 "register_operand" ""))]
3297   "(reload_completed
3298     && dead_or_set_p (insn, operands[1])
3299     && !reg_mentioned_p (operands[1], operands[0]))"
3300   [(set (match_dup 3) (match_dup 1))
3301    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3302               (clobber (reg:CC FLAGS_REG))])
3303    (set (match_dup 4) (match_dup 1))]
3304   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3306 ;; Extend to memory case when source register does not die.
3307 (define_split 
3308   [(set (match_operand:DI 0 "memory_operand" "")
3309         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3310    (clobber (reg:CC FLAGS_REG))
3311    (clobber (match_operand:SI 2 "register_operand" ""))]
3312   "reload_completed"
3313   [(const_int 0)]
3315   split_di (&operands[0], 1, &operands[3], &operands[4]);
3317   emit_move_insn (operands[3], operands[1]);
3319   /* Generate a cltd if possible and doing so it profitable.  */
3320   if (true_regnum (operands[1]) == 0
3321       && true_regnum (operands[2]) == 1
3322       && (optimize_size || TARGET_USE_CLTD))
3323     {
3324       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3325     }
3326   else
3327     {
3328       emit_move_insn (operands[2], operands[1]);
3329       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3330     }
3331   emit_move_insn (operands[4], operands[2]);
3332   DONE;
3335 ;; Extend to register case.  Optimize case where source and destination
3336 ;; registers match and cases where we can use cltd.
3337 (define_split 
3338   [(set (match_operand:DI 0 "register_operand" "")
3339         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3340    (clobber (reg:CC FLAGS_REG))
3341    (clobber (match_scratch:SI 2 ""))]
3342   "reload_completed"
3343   [(const_int 0)]
3345   split_di (&operands[0], 1, &operands[3], &operands[4]);
3347   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3348     emit_move_insn (operands[3], operands[1]);
3350   /* Generate a cltd if possible and doing so it profitable.  */
3351   if (true_regnum (operands[3]) == 0
3352       && (optimize_size || TARGET_USE_CLTD))
3353     {
3354       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3355       DONE;
3356     }
3358   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3359     emit_move_insn (operands[4], operands[1]);
3361   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3362   DONE;
3365 (define_insn "extendhisi2"
3366   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3367         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3368   ""
3370   switch (get_attr_prefix_0f (insn))
3371     {
3372     case 0:
3373       return "{cwtl|cwde}";
3374     default:
3375       return "movs{wl|x}\t{%1,%0|%0, %1}";
3376     }
3378   [(set_attr "type" "imovx")
3379    (set_attr "mode" "SI")
3380    (set (attr "prefix_0f")
3381      ;; movsx is short decodable while cwtl is vector decoded.
3382      (if_then_else (and (eq_attr "cpu" "!k6")
3383                         (eq_attr "alternative" "0"))
3384         (const_string "0")
3385         (const_string "1")))
3386    (set (attr "modrm")
3387      (if_then_else (eq_attr "prefix_0f" "0")
3388         (const_string "0")
3389         (const_string "1")))])
3391 (define_insn "*extendhisi2_zext"
3392   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3393         (zero_extend:DI
3394           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3395   "TARGET_64BIT"
3397   switch (get_attr_prefix_0f (insn))
3398     {
3399     case 0:
3400       return "{cwtl|cwde}";
3401     default:
3402       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3403     }
3405   [(set_attr "type" "imovx")
3406    (set_attr "mode" "SI")
3407    (set (attr "prefix_0f")
3408      ;; movsx is short decodable while cwtl is vector decoded.
3409      (if_then_else (and (eq_attr "cpu" "!k6")
3410                         (eq_attr "alternative" "0"))
3411         (const_string "0")
3412         (const_string "1")))
3413    (set (attr "modrm")
3414      (if_then_else (eq_attr "prefix_0f" "0")
3415         (const_string "0")
3416         (const_string "1")))])
3418 (define_insn "extendqihi2"
3419   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3420         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3421   ""
3423   switch (get_attr_prefix_0f (insn))
3424     {
3425     case 0:
3426       return "{cbtw|cbw}";
3427     default:
3428       return "movs{bw|x}\t{%1,%0|%0, %1}";
3429     }
3431   [(set_attr "type" "imovx")
3432    (set_attr "mode" "HI")
3433    (set (attr "prefix_0f")
3434      ;; movsx is short decodable while cwtl is vector decoded.
3435      (if_then_else (and (eq_attr "cpu" "!k6")
3436                         (eq_attr "alternative" "0"))
3437         (const_string "0")
3438         (const_string "1")))
3439    (set (attr "modrm")
3440      (if_then_else (eq_attr "prefix_0f" "0")
3441         (const_string "0")
3442         (const_string "1")))])
3444 (define_insn "extendqisi2"
3445   [(set (match_operand:SI 0 "register_operand" "=r")
3446         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3447   ""
3448   "movs{bl|x}\t{%1,%0|%0, %1}"
3449    [(set_attr "type" "imovx")
3450     (set_attr "mode" "SI")])
3452 (define_insn "*extendqisi2_zext"
3453   [(set (match_operand:DI 0 "register_operand" "=r")
3454         (zero_extend:DI
3455           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3456   "TARGET_64BIT"
3457   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3458    [(set_attr "type" "imovx")
3459     (set_attr "mode" "SI")])
3461 ;; Conversions between float and double.
3463 ;; These are all no-ops in the model used for the 80387.  So just
3464 ;; emit moves.
3466 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3467 (define_insn "*dummy_extendsfdf2"
3468   [(set (match_operand:DF 0 "push_operand" "=<")
3469         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3470   "0"
3471   "#")
3473 (define_split
3474   [(set (match_operand:DF 0 "push_operand" "")
3475         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3476   "!TARGET_64BIT"
3477   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3478    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3480 (define_split
3481   [(set (match_operand:DF 0 "push_operand" "")
3482         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3483   "TARGET_64BIT"
3484   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3485    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3487 (define_insn "*dummy_extendsfxf2"
3488   [(set (match_operand:XF 0 "push_operand" "=<")
3489         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3490   "0"
3491   "#")
3493 (define_split
3494   [(set (match_operand:XF 0 "push_operand" "")
3495         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3496   ""
3497   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3498    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3499   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3501 (define_split
3502   [(set (match_operand:XF 0 "push_operand" "")
3503         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3504   "TARGET_64BIT"
3505   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3506    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3507   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3509 (define_split
3510   [(set (match_operand:XF 0 "push_operand" "")
3511         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3512   ""
3513   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3514    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3515   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3517 (define_split
3518   [(set (match_operand:XF 0 "push_operand" "")
3519         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3520   "TARGET_64BIT"
3521   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3522    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3523   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3525 (define_expand "extendsfdf2"
3526   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3527         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3528   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3530   /* ??? Needed for compress_float_constant since all fp constants
3531      are LEGITIMATE_CONSTANT_P.  */
3532   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3533     {
3534       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3535           && standard_80387_constant_p (operands[1]) > 0)
3536         {
3537           operands[1] = simplify_const_unary_operation
3538             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3539           emit_move_insn_1 (operands[0], operands[1]);
3540           DONE;
3541         }
3542       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3543     }
3546 (define_insn "*extendsfdf2_mixed"
3547   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3548         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3549   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3551   switch (which_alternative)
3552     {
3553     case 0:
3554       return output_387_reg_move (insn, operands);
3556     case 1:
3557       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3558         return "fstp%z0\t%y0";
3559       else
3560         return "fst%z0\t%y0";
3562     case 2:
3563       return "cvtss2sd\t{%1, %0|%0, %1}";
3565     default:
3566       gcc_unreachable ();
3567     }
3569   [(set_attr "type" "fmov,fmov,ssecvt")
3570    (set_attr "mode" "SF,XF,DF")])
3572 (define_insn "*extendsfdf2_sse"
3573   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3574         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3575   "TARGET_SSE2 && TARGET_SSE_MATH"
3576   "cvtss2sd\t{%1, %0|%0, %1}"
3577   [(set_attr "type" "ssecvt")
3578    (set_attr "mode" "DF")])
3580 (define_insn "*extendsfdf2_i387"
3581   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3582         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3583   "TARGET_80387"
3585   switch (which_alternative)
3586     {
3587     case 0:
3588       return output_387_reg_move (insn, operands);
3590     case 1:
3591       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3592         return "fstp%z0\t%y0";
3593       else
3594         return "fst%z0\t%y0";
3596     default:
3597       gcc_unreachable ();
3598     }
3600   [(set_attr "type" "fmov")
3601    (set_attr "mode" "SF,XF")])
3603 (define_expand "extendsfxf2"
3604   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3605         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3606   "TARGET_80387"
3608   /* ??? Needed for compress_float_constant since all fp constants
3609      are LEGITIMATE_CONSTANT_P.  */
3610   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3611     {
3612       if (standard_80387_constant_p (operands[1]) > 0)
3613         {
3614           operands[1] = simplify_const_unary_operation
3615             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3616           emit_move_insn_1 (operands[0], operands[1]);
3617           DONE;
3618         }
3619       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3620     }
3623 (define_insn "*extendsfxf2_i387"
3624   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3625         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3626   "TARGET_80387"
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";
3638       else
3639         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3641     default:
3642       gcc_unreachable ();
3643     }
3645   [(set_attr "type" "fmov")
3646    (set_attr "mode" "SF,XF")])
3648 (define_expand "extenddfxf2"
3649   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3650         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3651   "TARGET_80387"
3653   /* ??? Needed for compress_float_constant since all fp constants
3654      are LEGITIMATE_CONSTANT_P.  */
3655   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3656     {
3657       if (standard_80387_constant_p (operands[1]) > 0)
3658         {
3659           operands[1] = simplify_const_unary_operation
3660             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3661           emit_move_insn_1 (operands[0], operands[1]);
3662           DONE;
3663         }
3664       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3665     }
3668 (define_insn "*extenddfxf2_i387"
3669   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3670         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3671   "TARGET_80387"
3673   switch (which_alternative)
3674     {
3675     case 0:
3676       return output_387_reg_move (insn, operands);
3678     case 1:
3679       /* There is no non-popping store to memory for XFmode.  So if
3680          we need one, follow the store with a load.  */
3681       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3682         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3683       else
3684         return "fstp%z0\t%y0";
3686     default:
3687       gcc_unreachable ();
3688     }
3690   [(set_attr "type" "fmov")
3691    (set_attr "mode" "DF,XF")])
3693 ;; %%% This seems bad bad news.
3694 ;; This cannot output into an f-reg because there is no way to be sure
3695 ;; of truncating in that case.  Otherwise this is just like a simple move
3696 ;; insn.  So we pretend we can output to a reg in order to get better
3697 ;; register preferencing, but we really use a stack slot.
3699 ;; Conversion from DFmode to SFmode.
3701 (define_expand "truncdfsf2"
3702   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3703         (float_truncate:SF
3704           (match_operand:DF 1 "nonimmediate_operand" "")))]
3705   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3707   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3708     ;
3709   else if (flag_unsafe_math_optimizations)
3710     ;
3711   else
3712     {
3713       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3714       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3715       DONE;
3716     }
3719 (define_expand "truncdfsf2_with_temp"
3720   [(parallel [(set (match_operand:SF 0 "" "")
3721                    (float_truncate:SF (match_operand:DF 1 "" "")))
3722               (clobber (match_operand:SF 2 "" ""))])]
3723   "")
3725 (define_insn "*truncdfsf_fast_mixed"
3726   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3727         (float_truncate:SF
3728           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3729   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3731   switch (which_alternative)
3732     {
3733     case 0:
3734       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3735         return "fstp%z0\t%y0";
3736       else
3737         return "fst%z0\t%y0";
3738     case 1:
3739       return output_387_reg_move (insn, operands);
3740     case 2:
3741       return "cvtsd2ss\t{%1, %0|%0, %1}";
3742     default:
3743       gcc_unreachable ();
3744     }
3746   [(set_attr "type" "fmov,fmov,ssecvt")
3747    (set_attr "mode" "SF")])
3749 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3750 ;; because nothing we do here is unsafe.
3751 (define_insn "*truncdfsf_fast_sse"
3752   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3753         (float_truncate:SF
3754           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3755   "TARGET_SSE2 && TARGET_SSE_MATH"
3756   "cvtsd2ss\t{%1, %0|%0, %1}"
3757   [(set_attr "type" "ssecvt")
3758    (set_attr "mode" "SF")])
3760 (define_insn "*truncdfsf_fast_i387"
3761   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3762         (float_truncate:SF
3763           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3764   "TARGET_80387 && flag_unsafe_math_optimizations"
3765   "* return output_387_reg_move (insn, operands);"
3766   [(set_attr "type" "fmov")
3767    (set_attr "mode" "SF")])
3769 (define_insn "*truncdfsf_mixed"
3770   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3771         (float_truncate:SF
3772           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3773    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3774   "TARGET_MIX_SSE_I387"
3776   switch (which_alternative)
3777     {
3778     case 0:
3779       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3780         return "fstp%z0\t%y0";
3781       else
3782         return "fst%z0\t%y0";
3783     case 1:
3784       return "#";
3785     case 2:
3786       return "cvtsd2ss\t{%1, %0|%0, %1}";
3787     default:
3788       gcc_unreachable ();
3789     }
3791   [(set_attr "type" "fmov,multi,ssecvt")
3792    (set_attr "unit" "*,i387,*")
3793    (set_attr "mode" "SF")])
3795 (define_insn "*truncdfsf_i387"
3796   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3797         (float_truncate:SF
3798           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3799    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3800   "TARGET_80387"
3802   switch (which_alternative)
3803     {
3804     case 0:
3805       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3806         return "fstp%z0\t%y0";
3807       else
3808         return "fst%z0\t%y0";
3809     case 1:
3810       return "#";
3811     default:
3812       gcc_unreachable ();
3813     }
3815   [(set_attr "type" "fmov,multi")
3816    (set_attr "unit" "*,i387")
3817    (set_attr "mode" "SF")])
3819 (define_insn "*truncdfsf2_i387_1"
3820   [(set (match_operand:SF 0 "memory_operand" "=m")
3821         (float_truncate:SF
3822           (match_operand:DF 1 "register_operand" "f")))]
3823   "TARGET_80387
3824    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3825    && !TARGET_MIX_SSE_I387"
3827   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3828     return "fstp%z0\t%y0";
3829   else
3830     return "fst%z0\t%y0";
3832   [(set_attr "type" "fmov")
3833    (set_attr "mode" "SF")])
3835 (define_split
3836   [(set (match_operand:SF 0 "register_operand" "")
3837         (float_truncate:SF
3838          (match_operand:DF 1 "fp_register_operand" "")))
3839    (clobber (match_operand 2 "" ""))]
3840   "reload_completed"
3841   [(set (match_dup 2) (match_dup 1))
3842    (set (match_dup 0) (match_dup 2))]
3844   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3847 ;; Conversion from XFmode to SFmode.
3849 (define_expand "truncxfsf2"
3850   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3851                    (float_truncate:SF
3852                     (match_operand:XF 1 "register_operand" "")))
3853               (clobber (match_dup 2))])]
3854   "TARGET_80387"
3856   if (flag_unsafe_math_optimizations)
3857     {
3858       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3859       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3860       if (reg != operands[0])
3861         emit_move_insn (operands[0], reg);
3862       DONE;
3863     }
3864   else
3865     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3868 (define_insn "*truncxfsf2_mixed"
3869   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3870         (float_truncate:SF
3871          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3872    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3873   "TARGET_MIX_SSE_I387"
3875   gcc_assert (!which_alternative);
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,multi,multi,multi")
3882    (set_attr "unit" "*,i387,i387,i387")
3883    (set_attr "mode" "SF")])
3885 (define_insn "truncxfsf2_i387_noop"
3886   [(set (match_operand:SF 0 "register_operand" "=f")
3887         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3888   "TARGET_80387 && flag_unsafe_math_optimizations"
3890   return output_387_reg_move (insn, operands);
3892   [(set_attr "type" "fmov")
3893    (set_attr "mode" "SF")])
3895 (define_insn "*truncxfsf2_i387"
3896   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3897         (float_truncate:SF
3898          (match_operand:XF 1 "register_operand" "f,f,f")))
3899    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3900   "TARGET_80387"
3902   gcc_assert (!which_alternative);
3903   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3904     return "fstp%z0\t%y0";
3905    else
3906      return "fst%z0\t%y0";
3908   [(set_attr "type" "fmov,multi,multi")
3909    (set_attr "unit" "*,i387,i387")
3910    (set_attr "mode" "SF")])
3912 (define_insn "*truncxfsf2_i387_1"
3913   [(set (match_operand:SF 0 "memory_operand" "=m")
3914         (float_truncate:SF
3915          (match_operand:XF 1 "register_operand" "f")))]
3916   "TARGET_80387"
3918   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3919     return "fstp%z0\t%y0";
3920   else
3921     return "fst%z0\t%y0";
3923   [(set_attr "type" "fmov")
3924    (set_attr "mode" "SF")])
3926 (define_split
3927   [(set (match_operand:SF 0 "register_operand" "")
3928         (float_truncate:SF
3929          (match_operand:XF 1 "register_operand" "")))
3930    (clobber (match_operand:SF 2 "memory_operand" ""))]
3931   "TARGET_80387 && reload_completed"
3932   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3933    (set (match_dup 0) (match_dup 2))]
3934   "")
3936 (define_split
3937   [(set (match_operand:SF 0 "memory_operand" "")
3938         (float_truncate:SF
3939          (match_operand:XF 1 "register_operand" "")))
3940    (clobber (match_operand:SF 2 "memory_operand" ""))]
3941   "TARGET_80387"
3942   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3943   "")
3945 ;; Conversion from XFmode to DFmode.
3947 (define_expand "truncxfdf2"
3948   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3949                    (float_truncate:DF
3950                     (match_operand:XF 1 "register_operand" "")))
3951               (clobber (match_dup 2))])]
3952   "TARGET_80387"
3954   if (flag_unsafe_math_optimizations)
3955     {
3956       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3957       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3958       if (reg != operands[0])
3959         emit_move_insn (operands[0], reg);
3960       DONE;
3961     }
3962   else
3963     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3966 (define_insn "*truncxfdf2_mixed"
3967   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3968         (float_truncate:DF
3969          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3970    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3971   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3973   gcc_assert (!which_alternative);
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,multi,multi,multi")
3980    (set_attr "unit" "*,i387,i387,i387")
3981    (set_attr "mode" "DF")])
3983 (define_insn "truncxfdf2_i387_noop"
3984   [(set (match_operand:DF 0 "register_operand" "=f")
3985         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3986   "TARGET_80387 && flag_unsafe_math_optimizations"
3988   return output_387_reg_move (insn, operands);
3990   [(set_attr "type" "fmov")
3991    (set_attr "mode" "DF")])
3993 (define_insn "*truncxfdf2_i387"
3994   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
3995         (float_truncate:DF
3996          (match_operand:XF 1 "register_operand" "f,f,f")))
3997    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3998   "TARGET_80387"
4000   gcc_assert (!which_alternative);
4001   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4002     return "fstp%z0\t%y0";
4003   else
4004     return "fst%z0\t%y0";
4006   [(set_attr "type" "fmov,multi,multi")
4007    (set_attr "unit" "*,i387,i387")
4008    (set_attr "mode" "DF")])
4010 (define_insn "*truncxfdf2_i387_1"
4011   [(set (match_operand:DF 0 "memory_operand" "=m")
4012         (float_truncate:DF
4013           (match_operand:XF 1 "register_operand" "f")))]
4014   "TARGET_80387"
4016   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4017     return "fstp%z0\t%y0";
4018   else
4019     return "fst%z0\t%y0";
4021   [(set_attr "type" "fmov")
4022    (set_attr "mode" "DF")])
4024 (define_split
4025   [(set (match_operand:DF 0 "register_operand" "")
4026         (float_truncate:DF
4027          (match_operand:XF 1 "register_operand" "")))
4028    (clobber (match_operand:DF 2 "memory_operand" ""))]
4029   "TARGET_80387 && reload_completed"
4030   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4031    (set (match_dup 0) (match_dup 2))]
4032   "")
4034 (define_split
4035   [(set (match_operand:DF 0 "memory_operand" "")
4036         (float_truncate:DF
4037          (match_operand:XF 1 "register_operand" "")))
4038    (clobber (match_operand:DF 2 "memory_operand" ""))]
4039   "TARGET_80387"
4040   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4041   "")
4043 ;; Signed conversion to DImode.
4045 (define_expand "fix_truncxfdi2"
4046   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4047                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4048               (clobber (reg:CC FLAGS_REG))])]
4049   "TARGET_80387"
4051   if (TARGET_FISTTP)
4052    {
4053      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4054      DONE;
4055    }
4058 (define_expand "fix_trunc<mode>di2"
4059   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4060                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4061               (clobber (reg:CC FLAGS_REG))])]
4062   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4064   if (TARGET_FISTTP
4065       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4066    {
4067      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4068      DONE;
4069    }
4070   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4071    {
4072      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4073      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4074      if (out != operands[0])
4075         emit_move_insn (operands[0], out);
4076      DONE;
4077    }
4080 ;; Signed conversion to SImode.
4082 (define_expand "fix_truncxfsi2"
4083   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4084                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4085               (clobber (reg:CC FLAGS_REG))])]
4086   "TARGET_80387"
4088   if (TARGET_FISTTP)
4089    {
4090      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4091      DONE;
4092    }
4095 (define_expand "fix_trunc<mode>si2"
4096   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4097                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4098               (clobber (reg:CC FLAGS_REG))])]
4099   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4101   if (TARGET_FISTTP
4102       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4103    {
4104      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4105      DONE;
4106    }
4107   if (SSE_FLOAT_MODE_P (<MODE>mode))
4108    {
4109      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4110      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4111      if (out != operands[0])
4112         emit_move_insn (operands[0], out);
4113      DONE;
4114    }
4117 ;; Signed conversion to HImode.
4119 (define_expand "fix_trunc<mode>hi2"
4120   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4121                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4122               (clobber (reg:CC FLAGS_REG))])]
4123   "TARGET_80387
4124    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4126   if (TARGET_FISTTP)
4127    {
4128      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4129      DONE;
4130    }
4133 ;; When SSE is available, it is always faster to use it!
4134 (define_insn "fix_truncsfdi_sse"
4135   [(set (match_operand:DI 0 "register_operand" "=r,r")
4136         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4137   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4138   "cvttss2si{q}\t{%1, %0|%0, %1}"
4139   [(set_attr "type" "sseicvt")
4140    (set_attr "mode" "SF")
4141    (set_attr "athlon_decode" "double,vector")])
4143 (define_insn "fix_truncdfdi_sse"
4144   [(set (match_operand:DI 0 "register_operand" "=r,r")
4145         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4146   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4147   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4148   [(set_attr "type" "sseicvt")
4149    (set_attr "mode" "DF")
4150    (set_attr "athlon_decode" "double,vector")])
4152 (define_insn "fix_truncsfsi_sse"
4153   [(set (match_operand:SI 0 "register_operand" "=r,r")
4154         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4155   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4156   "cvttss2si\t{%1, %0|%0, %1}"
4157   [(set_attr "type" "sseicvt")
4158    (set_attr "mode" "DF")
4159    (set_attr "athlon_decode" "double,vector")])
4161 (define_insn "fix_truncdfsi_sse"
4162   [(set (match_operand:SI 0 "register_operand" "=r,r")
4163         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4164   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4165   "cvttsd2si\t{%1, %0|%0, %1}"
4166   [(set_attr "type" "sseicvt")
4167    (set_attr "mode" "DF")
4168    (set_attr "athlon_decode" "double,vector")])
4170 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4171 (define_peephole2
4172   [(set (match_operand:DF 0 "register_operand" "")
4173         (match_operand:DF 1 "memory_operand" ""))
4174    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4175         (fix:SSEMODEI24 (match_dup 0)))]
4176   "!TARGET_K8
4177    && peep2_reg_dead_p (2, operands[0])"
4178   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4179   "")
4181 (define_peephole2
4182   [(set (match_operand:SF 0 "register_operand" "")
4183         (match_operand:SF 1 "memory_operand" ""))
4184    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4185         (fix:SSEMODEI24 (match_dup 0)))]
4186   "!TARGET_K8
4187    && peep2_reg_dead_p (2, operands[0])"
4188   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4189   "")
4191 ;; Avoid vector decoded forms of the instruction.
4192 (define_peephole2
4193   [(match_scratch:DF 2 "Y")
4194    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4195         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4196   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4197   [(set (match_dup 2) (match_dup 1))
4198    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4199   "")
4201 (define_peephole2
4202   [(match_scratch:SF 2 "x")
4203    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4204         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4205   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4206   [(set (match_dup 2) (match_dup 1))
4207    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4208   "")
4210 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4211   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4212         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4213   "TARGET_FISTTP
4214    && FLOAT_MODE_P (GET_MODE (operands[1]))
4215    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4216          && (TARGET_64BIT || <MODE>mode != DImode))
4217         && TARGET_SSE_MATH)
4218    && !(reload_completed || reload_in_progress)"
4219   "#"
4220   "&& 1"
4221   [(const_int 0)]
4223   if (memory_operand (operands[0], VOIDmode))
4224     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4225   else
4226     {
4227       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4228       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4229                                                             operands[1],
4230                                                             operands[2]));
4231     }
4232   DONE;
4234   [(set_attr "type" "fisttp")
4235    (set_attr "mode" "<MODE>")])
4237 (define_insn "fix_trunc<mode>_i387_fisttp"
4238   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4239         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4240    (clobber (match_scratch:XF 2 "=&1f"))]
4241   "TARGET_FISTTP
4242    && FLOAT_MODE_P (GET_MODE (operands[1]))
4243    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4244          && (TARGET_64BIT || <MODE>mode != DImode))
4245         && TARGET_SSE_MATH)"
4246   "* return output_fix_trunc (insn, operands, 1);"
4247   [(set_attr "type" "fisttp")
4248    (set_attr "mode" "<MODE>")])
4250 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4251   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4252         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4253    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4254    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4255   "TARGET_FISTTP
4256    && FLOAT_MODE_P (GET_MODE (operands[1]))
4257    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4258         && (TARGET_64BIT || <MODE>mode != DImode))
4259         && TARGET_SSE_MATH)"
4260   "#"
4261   [(set_attr "type" "fisttp")
4262    (set_attr "mode" "<MODE>")])
4264 (define_split
4265   [(set (match_operand:X87MODEI 0 "register_operand" "")
4266         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4267    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4268    (clobber (match_scratch 3 ""))]
4269   "reload_completed"
4270   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4271               (clobber (match_dup 3))])
4272    (set (match_dup 0) (match_dup 2))]
4273   "")
4275 (define_split
4276   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4277         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4278    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4279    (clobber (match_scratch 3 ""))]
4280   "reload_completed"
4281   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4282               (clobber (match_dup 3))])]
4283   "")
4285 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4286 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4287 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4288 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4289 ;; function in i386.c.
4290 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4291   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4292         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4293    (clobber (reg:CC FLAGS_REG))]
4294   "TARGET_80387 && !TARGET_FISTTP
4295    && FLOAT_MODE_P (GET_MODE (operands[1]))
4296    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4297          && (TARGET_64BIT || <MODE>mode != DImode))
4298    && !(reload_completed || reload_in_progress)"
4299   "#"
4300   "&& 1"
4301   [(const_int 0)]
4303   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4305   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4306   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4307   if (memory_operand (operands[0], VOIDmode))
4308     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4309                                          operands[2], operands[3]));
4310   else
4311     {
4312       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4313       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4314                                                      operands[2], operands[3],
4315                                                      operands[4]));
4316     }
4317   DONE;
4319   [(set_attr "type" "fistp")
4320    (set_attr "i387_cw" "trunc")
4321    (set_attr "mode" "<MODE>")])
4323 (define_insn "fix_truncdi_i387"
4324   [(set (match_operand:DI 0 "memory_operand" "=m")
4325         (fix:DI (match_operand 1 "register_operand" "f")))
4326    (use (match_operand:HI 2 "memory_operand" "m"))
4327    (use (match_operand:HI 3 "memory_operand" "m"))
4328    (clobber (match_scratch:XF 4 "=&1f"))]
4329   "TARGET_80387 && !TARGET_FISTTP
4330    && FLOAT_MODE_P (GET_MODE (operands[1]))
4331    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4332   "* return output_fix_trunc (insn, operands, 0);"
4333   [(set_attr "type" "fistp")
4334    (set_attr "i387_cw" "trunc")
4335    (set_attr "mode" "DI")])
4337 (define_insn "fix_truncdi_i387_with_temp"
4338   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4339         (fix:DI (match_operand 1 "register_operand" "f,f")))
4340    (use (match_operand:HI 2 "memory_operand" "m,m"))
4341    (use (match_operand:HI 3 "memory_operand" "m,m"))
4342    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4343    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4344   "TARGET_80387 && !TARGET_FISTTP
4345    && FLOAT_MODE_P (GET_MODE (operands[1]))
4346    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4347   "#"
4348   [(set_attr "type" "fistp")
4349    (set_attr "i387_cw" "trunc")
4350    (set_attr "mode" "DI")])
4352 (define_split 
4353   [(set (match_operand:DI 0 "register_operand" "")
4354         (fix:DI (match_operand 1 "register_operand" "")))
4355    (use (match_operand:HI 2 "memory_operand" ""))
4356    (use (match_operand:HI 3 "memory_operand" ""))
4357    (clobber (match_operand:DI 4 "memory_operand" ""))
4358    (clobber (match_scratch 5 ""))]
4359   "reload_completed"
4360   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4361               (use (match_dup 2))
4362               (use (match_dup 3))
4363               (clobber (match_dup 5))])
4364    (set (match_dup 0) (match_dup 4))]
4365   "")
4367 (define_split 
4368   [(set (match_operand:DI 0 "memory_operand" "")
4369         (fix:DI (match_operand 1 "register_operand" "")))
4370    (use (match_operand:HI 2 "memory_operand" ""))
4371    (use (match_operand:HI 3 "memory_operand" ""))
4372    (clobber (match_operand:DI 4 "memory_operand" ""))
4373    (clobber (match_scratch 5 ""))]
4374   "reload_completed"
4375   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4376               (use (match_dup 2))
4377               (use (match_dup 3))
4378               (clobber (match_dup 5))])]
4379   "")
4381 (define_insn "fix_trunc<mode>_i387"
4382   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4383         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4384    (use (match_operand:HI 2 "memory_operand" "m"))
4385    (use (match_operand:HI 3 "memory_operand" "m"))]
4386   "TARGET_80387 && !TARGET_FISTTP
4387    && FLOAT_MODE_P (GET_MODE (operands[1]))
4388    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4389   "* return output_fix_trunc (insn, operands, 0);"
4390   [(set_attr "type" "fistp")
4391    (set_attr "i387_cw" "trunc")
4392    (set_attr "mode" "<MODE>")])
4394 (define_insn "fix_trunc<mode>_i387_with_temp"
4395   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4396         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4397    (use (match_operand:HI 2 "memory_operand" "m,m"))
4398    (use (match_operand:HI 3 "memory_operand" "m,m"))
4399    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4400   "TARGET_80387 && !TARGET_FISTTP
4401    && FLOAT_MODE_P (GET_MODE (operands[1]))
4402    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4403   "#"
4404   [(set_attr "type" "fistp")
4405    (set_attr "i387_cw" "trunc")
4406    (set_attr "mode" "<MODE>")])
4408 (define_split 
4409   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4410         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4411    (use (match_operand:HI 2 "memory_operand" ""))
4412    (use (match_operand:HI 3 "memory_operand" ""))
4413    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4414   "reload_completed"
4415   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4416               (use (match_dup 2))
4417               (use (match_dup 3))])
4418    (set (match_dup 0) (match_dup 4))]
4419   "")
4421 (define_split 
4422   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4423         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4424    (use (match_operand:HI 2 "memory_operand" ""))
4425    (use (match_operand:HI 3 "memory_operand" ""))
4426    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4427   "reload_completed"
4428   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4429               (use (match_dup 2))
4430               (use (match_dup 3))])]
4431   "")
4433 (define_insn "x86_fnstcw_1"
4434   [(set (match_operand:HI 0 "memory_operand" "=m")
4435         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4436   "TARGET_80387"
4437   "fnstcw\t%0"
4438   [(set_attr "length" "2")
4439    (set_attr "mode" "HI")
4440    (set_attr "unit" "i387")])
4442 (define_insn "x86_fldcw_1"
4443   [(set (reg:HI FPCR_REG)
4444         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4445   "TARGET_80387"
4446   "fldcw\t%0"
4447   [(set_attr "length" "2")
4448    (set_attr "mode" "HI")
4449    (set_attr "unit" "i387")
4450    (set_attr "athlon_decode" "vector")])
4452 ;; Conversion between fixed point and floating point.
4454 ;; Even though we only accept memory inputs, the backend _really_
4455 ;; wants to be able to do this between registers.
4457 (define_expand "floathisf2"
4458   [(set (match_operand:SF 0 "register_operand" "")
4459         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4460   "TARGET_80387 || TARGET_SSE_MATH"
4462   if (TARGET_SSE_MATH)
4463     {
4464       emit_insn (gen_floatsisf2 (operands[0],
4465                                  convert_to_mode (SImode, operands[1], 0)));
4466       DONE;
4467     }
4470 (define_insn "*floathisf2_i387"
4471   [(set (match_operand:SF 0 "register_operand" "=f,f")
4472         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4473   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4474   "@
4475    fild%z1\t%1
4476    #"
4477   [(set_attr "type" "fmov,multi")
4478    (set_attr "mode" "SF")
4479    (set_attr "unit" "*,i387")
4480    (set_attr "fp_int_src" "true")])
4482 (define_expand "floatsisf2"
4483   [(set (match_operand:SF 0 "register_operand" "")
4484         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4485   "TARGET_80387 || TARGET_SSE_MATH"
4486   "")
4488 (define_insn "*floatsisf2_mixed"
4489   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4490         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4491   "TARGET_MIX_SSE_I387"
4492   "@
4493    fild%z1\t%1
4494    #
4495    cvtsi2ss\t{%1, %0|%0, %1}
4496    cvtsi2ss\t{%1, %0|%0, %1}"
4497   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4498    (set_attr "mode" "SF")
4499    (set_attr "unit" "*,i387,*,*")
4500    (set_attr "athlon_decode" "*,*,vector,double")
4501    (set_attr "fp_int_src" "true")])
4503 (define_insn "*floatsisf2_sse"
4504   [(set (match_operand:SF 0 "register_operand" "=x,x")
4505         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4506   "TARGET_SSE_MATH"
4507   "cvtsi2ss\t{%1, %0|%0, %1}"
4508   [(set_attr "type" "sseicvt")
4509    (set_attr "mode" "SF")
4510    (set_attr "athlon_decode" "vector,double")
4511    (set_attr "fp_int_src" "true")])
4513 (define_insn "*floatsisf2_i387"
4514   [(set (match_operand:SF 0 "register_operand" "=f,f")
4515         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4516   "TARGET_80387"
4517   "@
4518    fild%z1\t%1
4519    #"
4520   [(set_attr "type" "fmov,multi")
4521    (set_attr "mode" "SF")
4522    (set_attr "unit" "*,i387")
4523    (set_attr "fp_int_src" "true")])
4525 (define_expand "floatdisf2"
4526   [(set (match_operand:SF 0 "register_operand" "")
4527         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4528   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4529   "")
4531 (define_insn "*floatdisf2_mixed"
4532   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4533         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4534   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4535   "@
4536    fild%z1\t%1
4537    #
4538    cvtsi2ss{q}\t{%1, %0|%0, %1}
4539    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4540   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4541    (set_attr "mode" "SF")
4542    (set_attr "unit" "*,i387,*,*")
4543    (set_attr "athlon_decode" "*,*,vector,double")
4544    (set_attr "fp_int_src" "true")])
4546 (define_insn "*floatdisf2_sse"
4547   [(set (match_operand:SF 0 "register_operand" "=x,x")
4548         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4549   "TARGET_64BIT && TARGET_SSE_MATH"
4550   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4551   [(set_attr "type" "sseicvt")
4552    (set_attr "mode" "SF")
4553    (set_attr "athlon_decode" "vector,double")
4554    (set_attr "fp_int_src" "true")])
4556 (define_insn "*floatdisf2_i387"
4557   [(set (match_operand:SF 0 "register_operand" "=f,f")
4558         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4559   "TARGET_80387"
4560   "@
4561    fild%z1\t%1
4562    #"
4563   [(set_attr "type" "fmov,multi")
4564    (set_attr "mode" "SF")
4565    (set_attr "unit" "*,i387")
4566    (set_attr "fp_int_src" "true")])
4568 (define_expand "floathidf2"
4569   [(set (match_operand:DF 0 "register_operand" "")
4570         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4571   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4573   if (TARGET_SSE2 && TARGET_SSE_MATH)
4574     {
4575       emit_insn (gen_floatsidf2 (operands[0],
4576                                  convert_to_mode (SImode, operands[1], 0)));
4577       DONE;
4578     }
4581 (define_insn "*floathidf2_i387"
4582   [(set (match_operand:DF 0 "register_operand" "=f,f")
4583         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4584   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4585   "@
4586    fild%z1\t%1
4587    #"
4588   [(set_attr "type" "fmov,multi")
4589    (set_attr "mode" "DF")
4590    (set_attr "unit" "*,i387")
4591    (set_attr "fp_int_src" "true")])
4593 (define_expand "floatsidf2"
4594   [(set (match_operand:DF 0 "register_operand" "")
4595         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4596   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4597   "")
4599 (define_insn "*floatsidf2_mixed"
4600   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4601         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4602   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4603   "@
4604    fild%z1\t%1
4605    #
4606    cvtsi2sd\t{%1, %0|%0, %1}
4607    cvtsi2sd\t{%1, %0|%0, %1}"
4608   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4609    (set_attr "mode" "DF")
4610    (set_attr "unit" "*,i387,*,*")
4611    (set_attr "athlon_decode" "*,*,double,direct")
4612    (set_attr "fp_int_src" "true")])
4614 (define_insn "*floatsidf2_sse"
4615   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4616         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4617   "TARGET_SSE2 && TARGET_SSE_MATH"
4618   "cvtsi2sd\t{%1, %0|%0, %1}"
4619   [(set_attr "type" "sseicvt")
4620    (set_attr "mode" "DF")
4621    (set_attr "athlon_decode" "double,direct")
4622    (set_attr "fp_int_src" "true")])
4624 (define_insn "*floatsidf2_i387"
4625   [(set (match_operand:DF 0 "register_operand" "=f,f")
4626         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4627   "TARGET_80387"
4628   "@
4629    fild%z1\t%1
4630    #"
4631   [(set_attr "type" "fmov,multi")
4632    (set_attr "mode" "DF")
4633    (set_attr "unit" "*,i387")
4634    (set_attr "fp_int_src" "true")])
4636 (define_expand "floatdidf2"
4637   [(set (match_operand:DF 0 "register_operand" "")
4638         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4639   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4640   "")
4642 (define_insn "*floatdidf2_mixed"
4643   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4644         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4645   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4646   "@
4647    fild%z1\t%1
4648    #
4649    cvtsi2sd{q}\t{%1, %0|%0, %1}
4650    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4651   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4652    (set_attr "mode" "DF")
4653    (set_attr "unit" "*,i387,*,*")
4654    (set_attr "athlon_decode" "*,*,double,direct")
4655    (set_attr "fp_int_src" "true")])
4657 (define_insn "*floatdidf2_sse"
4658   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4659         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4660   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4661   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4662   [(set_attr "type" "sseicvt")
4663    (set_attr "mode" "DF")
4664    (set_attr "athlon_decode" "double,direct")
4665    (set_attr "fp_int_src" "true")])
4667 (define_insn "*floatdidf2_i387"
4668   [(set (match_operand:DF 0 "register_operand" "=f,f")
4669         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4670   "TARGET_80387"
4671   "@
4672    fild%z1\t%1
4673    #"
4674   [(set_attr "type" "fmov,multi")
4675    (set_attr "mode" "DF")
4676    (set_attr "unit" "*,i387")
4677    (set_attr "fp_int_src" "true")])
4679 (define_insn "floathixf2"
4680   [(set (match_operand:XF 0 "register_operand" "=f,f")
4681         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4682   "TARGET_80387"
4683   "@
4684    fild%z1\t%1
4685    #"
4686   [(set_attr "type" "fmov,multi")
4687    (set_attr "mode" "XF")
4688    (set_attr "unit" "*,i387")
4689    (set_attr "fp_int_src" "true")])
4691 (define_insn "floatsixf2"
4692   [(set (match_operand:XF 0 "register_operand" "=f,f")
4693         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4694   "TARGET_80387"
4695   "@
4696    fild%z1\t%1
4697    #"
4698   [(set_attr "type" "fmov,multi")
4699    (set_attr "mode" "XF")
4700    (set_attr "unit" "*,i387")
4701    (set_attr "fp_int_src" "true")])
4703 (define_insn "floatdixf2"
4704   [(set (match_operand:XF 0 "register_operand" "=f,f")
4705         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4706   "TARGET_80387"
4707   "@
4708    fild%z1\t%1
4709    #"
4710   [(set_attr "type" "fmov,multi")
4711    (set_attr "mode" "XF")
4712    (set_attr "unit" "*,i387")
4713    (set_attr "fp_int_src" "true")])
4715 ;; %%% Kill these when reload knows how to do it.
4716 (define_split
4717   [(set (match_operand 0 "fp_register_operand" "")
4718         (float (match_operand 1 "register_operand" "")))]
4719   "reload_completed
4720    && TARGET_80387
4721    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4722   [(const_int 0)]
4724   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4725   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4726   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4727   ix86_free_from_memory (GET_MODE (operands[1]));
4728   DONE;
4731 (define_expand "floatunssisf2"
4732   [(use (match_operand:SF 0 "register_operand" ""))
4733    (use (match_operand:SI 1 "register_operand" ""))]
4734   "!TARGET_64BIT && TARGET_SSE_MATH"
4735   "x86_emit_floatuns (operands); DONE;")
4737 (define_expand "floatunsdisf2"
4738   [(use (match_operand:SF 0 "register_operand" ""))
4739    (use (match_operand:DI 1 "register_operand" ""))]
4740   "TARGET_64BIT && TARGET_SSE_MATH"
4741   "x86_emit_floatuns (operands); DONE;")
4743 (define_expand "floatunsdidf2"
4744   [(use (match_operand:DF 0 "register_operand" ""))
4745    (use (match_operand:DI 1 "register_operand" ""))]
4746   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4747   "x86_emit_floatuns (operands); DONE;")
4749 ;; SSE extract/set expanders
4752 ;; Add instructions
4754 ;; %%% splits for addditi3
4756 (define_expand "addti3"
4757   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4758         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4759                  (match_operand:TI 2 "x86_64_general_operand" "")))
4760    (clobber (reg:CC FLAGS_REG))]
4761   "TARGET_64BIT"
4762   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4764 (define_insn "*addti3_1"
4765   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4766         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4767                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4768    (clobber (reg:CC FLAGS_REG))]
4769   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4770   "#")
4772 (define_split
4773   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4774         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4775                  (match_operand:TI 2 "general_operand" "")))
4776    (clobber (reg:CC FLAGS_REG))]
4777   "TARGET_64BIT && reload_completed"
4778   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4779                                           UNSPEC_ADD_CARRY))
4780               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4781    (parallel [(set (match_dup 3)
4782                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4783                                      (match_dup 4))
4784                             (match_dup 5)))
4785               (clobber (reg:CC FLAGS_REG))])]
4786   "split_ti (operands+0, 1, operands+0, operands+3);
4787    split_ti (operands+1, 1, operands+1, operands+4);
4788    split_ti (operands+2, 1, operands+2, operands+5);")
4790 ;; %%% splits for addsidi3
4791 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4792 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4793 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4795 (define_expand "adddi3"
4796   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4797         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4798                  (match_operand:DI 2 "x86_64_general_operand" "")))
4799    (clobber (reg:CC FLAGS_REG))]
4800   ""
4801   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4803 (define_insn "*adddi3_1"
4804   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4805         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4806                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4807    (clobber (reg:CC FLAGS_REG))]
4808   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4809   "#")
4811 (define_split
4812   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4813         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4814                  (match_operand:DI 2 "general_operand" "")))
4815    (clobber (reg:CC FLAGS_REG))]
4816   "!TARGET_64BIT && reload_completed"
4817   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4818                                           UNSPEC_ADD_CARRY))
4819               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4820    (parallel [(set (match_dup 3)
4821                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4822                                      (match_dup 4))
4823                             (match_dup 5)))
4824               (clobber (reg:CC FLAGS_REG))])]
4825   "split_di (operands+0, 1, operands+0, operands+3);
4826    split_di (operands+1, 1, operands+1, operands+4);
4827    split_di (operands+2, 1, operands+2, operands+5);")
4829 (define_insn "adddi3_carry_rex64"
4830   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4831           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4832                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4833                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4834    (clobber (reg:CC FLAGS_REG))]
4835   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4836   "adc{q}\t{%2, %0|%0, %2}"
4837   [(set_attr "type" "alu")
4838    (set_attr "pent_pair" "pu")
4839    (set_attr "mode" "DI")])
4841 (define_insn "*adddi3_cc_rex64"
4842   [(set (reg:CC FLAGS_REG)
4843         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4844                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4845                    UNSPEC_ADD_CARRY))
4846    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4847         (plus:DI (match_dup 1) (match_dup 2)))]
4848   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4849   "add{q}\t{%2, %0|%0, %2}"
4850   [(set_attr "type" "alu")
4851    (set_attr "mode" "DI")])
4853 (define_insn "addqi3_carry"
4854   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4855           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4856                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4857                    (match_operand:QI 2 "general_operand" "qi,qm")))
4858    (clobber (reg:CC FLAGS_REG))]
4859   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4860   "adc{b}\t{%2, %0|%0, %2}"
4861   [(set_attr "type" "alu")
4862    (set_attr "pent_pair" "pu")
4863    (set_attr "mode" "QI")])
4865 (define_insn "addhi3_carry"
4866   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4867           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4868                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4869                    (match_operand:HI 2 "general_operand" "ri,rm")))
4870    (clobber (reg:CC FLAGS_REG))]
4871   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4872   "adc{w}\t{%2, %0|%0, %2}"
4873   [(set_attr "type" "alu")
4874    (set_attr "pent_pair" "pu")
4875    (set_attr "mode" "HI")])
4877 (define_insn "addsi3_carry"
4878   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4879           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4880                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4881                    (match_operand:SI 2 "general_operand" "ri,rm")))
4882    (clobber (reg:CC FLAGS_REG))]
4883   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4884   "adc{l}\t{%2, %0|%0, %2}"
4885   [(set_attr "type" "alu")
4886    (set_attr "pent_pair" "pu")
4887    (set_attr "mode" "SI")])
4889 (define_insn "*addsi3_carry_zext"
4890   [(set (match_operand:DI 0 "register_operand" "=r")
4891           (zero_extend:DI 
4892             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4893                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4894                      (match_operand:SI 2 "general_operand" "rim"))))
4895    (clobber (reg:CC FLAGS_REG))]
4896   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4897   "adc{l}\t{%2, %k0|%k0, %2}"
4898   [(set_attr "type" "alu")
4899    (set_attr "pent_pair" "pu")
4900    (set_attr "mode" "SI")])
4902 (define_insn "*addsi3_cc"
4903   [(set (reg:CC FLAGS_REG)
4904         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4905                     (match_operand:SI 2 "general_operand" "ri,rm")]
4906                    UNSPEC_ADD_CARRY))
4907    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4908         (plus:SI (match_dup 1) (match_dup 2)))]
4909   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4910   "add{l}\t{%2, %0|%0, %2}"
4911   [(set_attr "type" "alu")
4912    (set_attr "mode" "SI")])
4914 (define_insn "addqi3_cc"
4915   [(set (reg:CC FLAGS_REG)
4916         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4917                     (match_operand:QI 2 "general_operand" "qi,qm")]
4918                    UNSPEC_ADD_CARRY))
4919    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4920         (plus:QI (match_dup 1) (match_dup 2)))]
4921   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4922   "add{b}\t{%2, %0|%0, %2}"
4923   [(set_attr "type" "alu")
4924    (set_attr "mode" "QI")])
4926 (define_expand "addsi3"
4927   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4928                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4929                             (match_operand:SI 2 "general_operand" "")))
4930               (clobber (reg:CC FLAGS_REG))])]
4931   ""
4932   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4934 (define_insn "*lea_1"
4935   [(set (match_operand:SI 0 "register_operand" "=r")
4936         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4937   "!TARGET_64BIT"
4938   "lea{l}\t{%a1, %0|%0, %a1}"
4939   [(set_attr "type" "lea")
4940    (set_attr "mode" "SI")])
4942 (define_insn "*lea_1_rex64"
4943   [(set (match_operand:SI 0 "register_operand" "=r")
4944         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4945   "TARGET_64BIT"
4946   "lea{l}\t{%a1, %0|%0, %a1}"
4947   [(set_attr "type" "lea")
4948    (set_attr "mode" "SI")])
4950 (define_insn "*lea_1_zext"
4951   [(set (match_operand:DI 0 "register_operand" "=r")
4952         (zero_extend:DI
4953          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4954   "TARGET_64BIT"
4955   "lea{l}\t{%a1, %k0|%k0, %a1}"
4956   [(set_attr "type" "lea")
4957    (set_attr "mode" "SI")])
4959 (define_insn "*lea_2_rex64"
4960   [(set (match_operand:DI 0 "register_operand" "=r")
4961         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4962   "TARGET_64BIT"
4963   "lea{q}\t{%a1, %0|%0, %a1}"
4964   [(set_attr "type" "lea")
4965    (set_attr "mode" "DI")])
4967 ;; The lea patterns for non-Pmodes needs to be matched by several
4968 ;; insns converted to real lea by splitters.
4970 (define_insn_and_split "*lea_general_1"
4971   [(set (match_operand 0 "register_operand" "=r")
4972         (plus (plus (match_operand 1 "index_register_operand" "l")
4973                     (match_operand 2 "register_operand" "r"))
4974               (match_operand 3 "immediate_operand" "i")))]
4975   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4976     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4977    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4978    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4979    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4980    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4981        || GET_MODE (operands[3]) == VOIDmode)"
4982   "#"
4983   "&& reload_completed"
4984   [(const_int 0)]
4986   rtx pat;
4987   operands[0] = gen_lowpart (SImode, operands[0]);
4988   operands[1] = gen_lowpart (Pmode, operands[1]);
4989   operands[2] = gen_lowpart (Pmode, operands[2]);
4990   operands[3] = gen_lowpart (Pmode, operands[3]);
4991   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4992                       operands[3]);
4993   if (Pmode != SImode)
4994     pat = gen_rtx_SUBREG (SImode, pat, 0);
4995   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4996   DONE;
4998   [(set_attr "type" "lea")
4999    (set_attr "mode" "SI")])
5001 (define_insn_and_split "*lea_general_1_zext"
5002   [(set (match_operand:DI 0 "register_operand" "=r")
5003         (zero_extend:DI
5004           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5005                             (match_operand:SI 2 "register_operand" "r"))
5006                    (match_operand:SI 3 "immediate_operand" "i"))))]
5007   "TARGET_64BIT"
5008   "#"
5009   "&& reload_completed"
5010   [(set (match_dup 0)
5011         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5012                                                      (match_dup 2))
5013                                             (match_dup 3)) 0)))]
5015   operands[1] = gen_lowpart (Pmode, operands[1]);
5016   operands[2] = gen_lowpart (Pmode, operands[2]);
5017   operands[3] = gen_lowpart (Pmode, operands[3]);
5019   [(set_attr "type" "lea")
5020    (set_attr "mode" "SI")])
5022 (define_insn_and_split "*lea_general_2"
5023   [(set (match_operand 0 "register_operand" "=r")
5024         (plus (mult (match_operand 1 "index_register_operand" "l")
5025                     (match_operand 2 "const248_operand" "i"))
5026               (match_operand 3 "nonmemory_operand" "ri")))]
5027   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5028     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5029    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5030    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5031    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5032        || GET_MODE (operands[3]) == VOIDmode)"
5033   "#"
5034   "&& reload_completed"
5035   [(const_int 0)]
5037   rtx pat;
5038   operands[0] = gen_lowpart (SImode, operands[0]);
5039   operands[1] = gen_lowpart (Pmode, operands[1]);
5040   operands[3] = gen_lowpart (Pmode, operands[3]);
5041   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5042                       operands[3]);
5043   if (Pmode != SImode)
5044     pat = gen_rtx_SUBREG (SImode, pat, 0);
5045   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5046   DONE;
5048   [(set_attr "type" "lea")
5049    (set_attr "mode" "SI")])
5051 (define_insn_and_split "*lea_general_2_zext"
5052   [(set (match_operand:DI 0 "register_operand" "=r")
5053         (zero_extend:DI
5054           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5055                             (match_operand:SI 2 "const248_operand" "n"))
5056                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5057   "TARGET_64BIT"
5058   "#"
5059   "&& reload_completed"
5060   [(set (match_dup 0)
5061         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5062                                                      (match_dup 2))
5063                                             (match_dup 3)) 0)))]
5065   operands[1] = gen_lowpart (Pmode, operands[1]);
5066   operands[3] = gen_lowpart (Pmode, operands[3]);
5068   [(set_attr "type" "lea")
5069    (set_attr "mode" "SI")])
5071 (define_insn_and_split "*lea_general_3"
5072   [(set (match_operand 0 "register_operand" "=r")
5073         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5074                           (match_operand 2 "const248_operand" "i"))
5075                     (match_operand 3 "register_operand" "r"))
5076               (match_operand 4 "immediate_operand" "i")))]
5077   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5078     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5079    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5080    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5081    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5082   "#"
5083   "&& reload_completed"
5084   [(const_int 0)]
5086   rtx pat;
5087   operands[0] = gen_lowpart (SImode, operands[0]);
5088   operands[1] = gen_lowpart (Pmode, operands[1]);
5089   operands[3] = gen_lowpart (Pmode, operands[3]);
5090   operands[4] = gen_lowpart (Pmode, operands[4]);
5091   pat = gen_rtx_PLUS (Pmode,
5092                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5093                                                          operands[2]),
5094                                     operands[3]),
5095                       operands[4]);
5096   if (Pmode != SImode)
5097     pat = gen_rtx_SUBREG (SImode, pat, 0);
5098   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5099   DONE;
5101   [(set_attr "type" "lea")
5102    (set_attr "mode" "SI")])
5104 (define_insn_and_split "*lea_general_3_zext"
5105   [(set (match_operand:DI 0 "register_operand" "=r")
5106         (zero_extend:DI
5107           (plus:SI (plus:SI (mult:SI
5108                               (match_operand:SI 1 "index_register_operand" "l")
5109                               (match_operand:SI 2 "const248_operand" "n"))
5110                             (match_operand:SI 3 "register_operand" "r"))
5111                    (match_operand:SI 4 "immediate_operand" "i"))))]
5112   "TARGET_64BIT"
5113   "#"
5114   "&& reload_completed"
5115   [(set (match_dup 0)
5116         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5117                                                               (match_dup 2))
5118                                                      (match_dup 3))
5119                                             (match_dup 4)) 0)))]
5121   operands[1] = gen_lowpart (Pmode, operands[1]);
5122   operands[3] = gen_lowpart (Pmode, operands[3]);
5123   operands[4] = gen_lowpart (Pmode, operands[4]);
5125   [(set_attr "type" "lea")
5126    (set_attr "mode" "SI")])
5128 (define_insn "*adddi_1_rex64"
5129   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5130         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5131                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5132    (clobber (reg:CC FLAGS_REG))]
5133   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5135   switch (get_attr_type (insn))
5136     {
5137     case TYPE_LEA:
5138       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5139       return "lea{q}\t{%a2, %0|%0, %a2}";
5141     case TYPE_INCDEC:
5142       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5143       if (operands[2] == const1_rtx)
5144         return "inc{q}\t%0";
5145       else
5146         {
5147           gcc_assert (operands[2] == constm1_rtx);
5148           return "dec{q}\t%0";
5149         }
5151     default:
5152       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5154       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5155          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5156       if (GET_CODE (operands[2]) == CONST_INT
5157           /* Avoid overflows.  */
5158           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5159           && (INTVAL (operands[2]) == 128
5160               || (INTVAL (operands[2]) < 0
5161                   && INTVAL (operands[2]) != -128)))
5162         {
5163           operands[2] = GEN_INT (-INTVAL (operands[2]));
5164           return "sub{q}\t{%2, %0|%0, %2}";
5165         }
5166       return "add{q}\t{%2, %0|%0, %2}";
5167     }
5169   [(set (attr "type")
5170      (cond [(eq_attr "alternative" "2")
5171               (const_string "lea")
5172             ; Current assemblers are broken and do not allow @GOTOFF in
5173             ; ought but a memory context.
5174             (match_operand:DI 2 "pic_symbolic_operand" "")
5175               (const_string "lea")
5176             (match_operand:DI 2 "incdec_operand" "")
5177               (const_string "incdec")
5178            ]
5179            (const_string "alu")))
5180    (set_attr "mode" "DI")])
5182 ;; Convert lea to the lea pattern to avoid flags dependency.
5183 (define_split
5184   [(set (match_operand:DI 0 "register_operand" "")
5185         (plus:DI (match_operand:DI 1 "register_operand" "")
5186                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5187    (clobber (reg:CC FLAGS_REG))]
5188   "TARGET_64BIT && reload_completed
5189    && true_regnum (operands[0]) != true_regnum (operands[1])"
5190   [(set (match_dup 0)
5191         (plus:DI (match_dup 1)
5192                  (match_dup 2)))]
5193   "")
5195 (define_insn "*adddi_2_rex64"
5196   [(set (reg FLAGS_REG)
5197         (compare
5198           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5199                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5200           (const_int 0)))                       
5201    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5202         (plus:DI (match_dup 1) (match_dup 2)))]
5203   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5204    && ix86_binary_operator_ok (PLUS, DImode, operands)
5205    /* Current assemblers are broken and do not allow @GOTOFF in
5206       ought but a memory context.  */
5207    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5209   switch (get_attr_type (insn))
5210     {
5211     case TYPE_INCDEC:
5212       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5213       if (operands[2] == const1_rtx)
5214         return "inc{q}\t%0";
5215       else
5216         {
5217           gcc_assert (operands[2] == constm1_rtx);
5218           return "dec{q}\t%0";
5219         }
5221     default:
5222       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5223       /* ???? We ought to handle there the 32bit case too
5224          - do we need new constraint?  */
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 (GET_CODE (operands[2]) == CONST_INT
5228           /* Avoid overflows.  */
5229           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5230           && (INTVAL (operands[2]) == 128
5231               || (INTVAL (operands[2]) < 0
5232                   && INTVAL (operands[2]) != -128)))
5233         {
5234           operands[2] = GEN_INT (-INTVAL (operands[2]));
5235           return "sub{q}\t{%2, %0|%0, %2}";
5236         }
5237       return "add{q}\t{%2, %0|%0, %2}";
5238     }
5240   [(set (attr "type")
5241      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5242         (const_string "incdec")
5243         (const_string "alu")))
5244    (set_attr "mode" "DI")])
5246 (define_insn "*adddi_3_rex64"
5247   [(set (reg FLAGS_REG)
5248         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5249                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5250    (clobber (match_scratch:DI 0 "=r"))]
5251   "TARGET_64BIT
5252    && ix86_match_ccmode (insn, CCZmode)
5253    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5254    /* Current assemblers are broken and do not allow @GOTOFF in
5255       ought but a memory context.  */
5256    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5258   switch (get_attr_type (insn))
5259     {
5260     case TYPE_INCDEC:
5261       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5262       if (operands[2] == const1_rtx)
5263         return "inc{q}\t%0";
5264       else
5265         {
5266           gcc_assert (operands[2] == constm1_rtx);
5267           return "dec{q}\t%0";
5268         }
5270     default:
5271       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5272       /* ???? We ought to handle there the 32bit case too
5273          - do we need new constraint?  */
5274       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5275          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5276       if (GET_CODE (operands[2]) == CONST_INT
5277           /* Avoid overflows.  */
5278           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5279           && (INTVAL (operands[2]) == 128
5280               || (INTVAL (operands[2]) < 0
5281                   && INTVAL (operands[2]) != -128)))
5282         {
5283           operands[2] = GEN_INT (-INTVAL (operands[2]));
5284           return "sub{q}\t{%2, %0|%0, %2}";
5285         }
5286       return "add{q}\t{%2, %0|%0, %2}";
5287     }
5289   [(set (attr "type")
5290      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5291         (const_string "incdec")
5292         (const_string "alu")))
5293    (set_attr "mode" "DI")])
5295 ; For comparisons against 1, -1 and 128, we may generate better code
5296 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5297 ; is matched then.  We can't accept general immediate, because for
5298 ; case of overflows,  the result is messed up.
5299 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5300 ; when negated.
5301 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5302 ; only for comparisons not depending on it.
5303 (define_insn "*adddi_4_rex64"
5304   [(set (reg FLAGS_REG)
5305         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5306                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5307    (clobber (match_scratch:DI 0 "=rm"))]
5308   "TARGET_64BIT
5309    &&  ix86_match_ccmode (insn, CCGCmode)"
5311   switch (get_attr_type (insn))
5312     {
5313     case TYPE_INCDEC:
5314       if (operands[2] == constm1_rtx)
5315         return "inc{q}\t%0";
5316       else
5317         {
5318           gcc_assert (operands[2] == const1_rtx);
5319           return "dec{q}\t%0";
5320         }
5322     default:
5323       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5324       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5325          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5326       if ((INTVAL (operands[2]) == -128
5327            || (INTVAL (operands[2]) > 0
5328                && INTVAL (operands[2]) != 128))
5329           /* Avoid overflows.  */
5330           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5331         return "sub{q}\t{%2, %0|%0, %2}";
5332       operands[2] = GEN_INT (-INTVAL (operands[2]));
5333       return "add{q}\t{%2, %0|%0, %2}";
5334     }
5336   [(set (attr "type")
5337      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5338         (const_string "incdec")
5339         (const_string "alu")))
5340    (set_attr "mode" "DI")])
5342 (define_insn "*adddi_5_rex64"
5343   [(set (reg FLAGS_REG)
5344         (compare
5345           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5346                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5347           (const_int 0)))                       
5348    (clobber (match_scratch:DI 0 "=r"))]
5349   "TARGET_64BIT
5350    && ix86_match_ccmode (insn, CCGOCmode)
5351    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5352    /* Current assemblers are broken and do not allow @GOTOFF in
5353       ought but a memory context.  */
5354    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5356   switch (get_attr_type (insn))
5357     {
5358     case TYPE_INCDEC:
5359       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360       if (operands[2] == const1_rtx)
5361         return "inc{q}\t%0";
5362       else
5363         {
5364           gcc_assert (operands[2] == constm1_rtx);
5365           return "dec{q}\t%0";
5366         }
5368     default:
5369       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5370       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5371          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5372       if (GET_CODE (operands[2]) == CONST_INT
5373           /* Avoid overflows.  */
5374           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5375           && (INTVAL (operands[2]) == 128
5376               || (INTVAL (operands[2]) < 0
5377                   && INTVAL (operands[2]) != -128)))
5378         {
5379           operands[2] = GEN_INT (-INTVAL (operands[2]));
5380           return "sub{q}\t{%2, %0|%0, %2}";
5381         }
5382       return "add{q}\t{%2, %0|%0, %2}";
5383     }
5385   [(set (attr "type")
5386      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5387         (const_string "incdec")
5388         (const_string "alu")))
5389    (set_attr "mode" "DI")])
5392 (define_insn "*addsi_1"
5393   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5394         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5395                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5396    (clobber (reg:CC FLAGS_REG))]
5397   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5399   switch (get_attr_type (insn))
5400     {
5401     case TYPE_LEA:
5402       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5403       return "lea{l}\t{%a2, %0|%0, %a2}";
5405     case TYPE_INCDEC:
5406       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5407       if (operands[2] == const1_rtx)
5408         return "inc{l}\t%0";
5409       else
5410         {
5411           gcc_assert (operands[2] == constm1_rtx);
5412           return "dec{l}\t%0";
5413         }
5415     default:
5416       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5418       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5419          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5420       if (GET_CODE (operands[2]) == CONST_INT
5421           && (INTVAL (operands[2]) == 128
5422               || (INTVAL (operands[2]) < 0
5423                   && INTVAL (operands[2]) != -128)))
5424         {
5425           operands[2] = GEN_INT (-INTVAL (operands[2]));
5426           return "sub{l}\t{%2, %0|%0, %2}";
5427         }
5428       return "add{l}\t{%2, %0|%0, %2}";
5429     }
5431   [(set (attr "type")
5432      (cond [(eq_attr "alternative" "2")
5433               (const_string "lea")
5434             ; Current assemblers are broken and do not allow @GOTOFF in
5435             ; ought but a memory context.
5436             (match_operand:SI 2 "pic_symbolic_operand" "")
5437               (const_string "lea")
5438             (match_operand:SI 2 "incdec_operand" "")
5439               (const_string "incdec")
5440            ]
5441            (const_string "alu")))
5442    (set_attr "mode" "SI")])
5444 ;; Convert lea to the lea pattern to avoid flags dependency.
5445 (define_split
5446   [(set (match_operand 0 "register_operand" "")
5447         (plus (match_operand 1 "register_operand" "")
5448               (match_operand 2 "nonmemory_operand" "")))
5449    (clobber (reg:CC FLAGS_REG))]
5450   "reload_completed
5451    && true_regnum (operands[0]) != true_regnum (operands[1])"
5452   [(const_int 0)]
5454   rtx pat;
5455   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5456      may confuse gen_lowpart.  */
5457   if (GET_MODE (operands[0]) != Pmode)
5458     {
5459       operands[1] = gen_lowpart (Pmode, operands[1]);
5460       operands[2] = gen_lowpart (Pmode, operands[2]);
5461     }
5462   operands[0] = gen_lowpart (SImode, operands[0]);
5463   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5464   if (Pmode != SImode)
5465     pat = gen_rtx_SUBREG (SImode, pat, 0);
5466   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5467   DONE;
5470 ;; It may seem that nonimmediate operand is proper one for operand 1.
5471 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5472 ;; we take care in ix86_binary_operator_ok to not allow two memory
5473 ;; operands so proper swapping will be done in reload.  This allow
5474 ;; patterns constructed from addsi_1 to match.
5475 (define_insn "addsi_1_zext"
5476   [(set (match_operand:DI 0 "register_operand" "=r,r")
5477         (zero_extend:DI
5478           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5479                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5480    (clobber (reg:CC FLAGS_REG))]
5481   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5483   switch (get_attr_type (insn))
5484     {
5485     case TYPE_LEA:
5486       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5487       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5489     case TYPE_INCDEC:
5490       if (operands[2] == const1_rtx)
5491         return "inc{l}\t%k0";
5492       else
5493         {
5494           gcc_assert (operands[2] == constm1_rtx);
5495           return "dec{l}\t%k0";
5496         }
5498     default:
5499       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5500          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5501       if (GET_CODE (operands[2]) == CONST_INT
5502           && (INTVAL (operands[2]) == 128
5503               || (INTVAL (operands[2]) < 0
5504                   && INTVAL (operands[2]) != -128)))
5505         {
5506           operands[2] = GEN_INT (-INTVAL (operands[2]));
5507           return "sub{l}\t{%2, %k0|%k0, %2}";
5508         }
5509       return "add{l}\t{%2, %k0|%k0, %2}";
5510     }
5512   [(set (attr "type")
5513      (cond [(eq_attr "alternative" "1")
5514               (const_string "lea")
5515             ; Current assemblers are broken and do not allow @GOTOFF in
5516             ; ought but a memory context.
5517             (match_operand:SI 2 "pic_symbolic_operand" "")
5518               (const_string "lea")
5519             (match_operand:SI 2 "incdec_operand" "")
5520               (const_string "incdec")
5521            ]
5522            (const_string "alu")))
5523    (set_attr "mode" "SI")])
5525 ;; Convert lea to the lea pattern to avoid flags dependency.
5526 (define_split
5527   [(set (match_operand:DI 0 "register_operand" "")
5528         (zero_extend:DI
5529           (plus:SI (match_operand:SI 1 "register_operand" "")
5530                    (match_operand:SI 2 "nonmemory_operand" ""))))
5531    (clobber (reg:CC FLAGS_REG))]
5532   "TARGET_64BIT && reload_completed
5533    && true_regnum (operands[0]) != true_regnum (operands[1])"
5534   [(set (match_dup 0)
5535         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5537   operands[1] = gen_lowpart (Pmode, operands[1]);
5538   operands[2] = gen_lowpart (Pmode, operands[2]);
5541 (define_insn "*addsi_2"
5542   [(set (reg FLAGS_REG)
5543         (compare
5544           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5545                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5546           (const_int 0)))                       
5547    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5548         (plus:SI (match_dup 1) (match_dup 2)))]
5549   "ix86_match_ccmode (insn, CCGOCmode)
5550    && ix86_binary_operator_ok (PLUS, SImode, operands)
5551    /* Current assemblers are broken and do not allow @GOTOFF in
5552       ought but a memory context.  */
5553    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555   switch (get_attr_type (insn))
5556     {
5557     case TYPE_INCDEC:
5558       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5559       if (operands[2] == const1_rtx)
5560         return "inc{l}\t%0";
5561       else
5562         {
5563           gcc_assert (operands[2] == constm1_rtx);
5564           return "dec{l}\t%0";
5565         }
5567     default:
5568       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5569       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5570          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5571       if (GET_CODE (operands[2]) == CONST_INT
5572           && (INTVAL (operands[2]) == 128
5573               || (INTVAL (operands[2]) < 0
5574                   && INTVAL (operands[2]) != -128)))
5575         {
5576           operands[2] = GEN_INT (-INTVAL (operands[2]));
5577           return "sub{l}\t{%2, %0|%0, %2}";
5578         }
5579       return "add{l}\t{%2, %0|%0, %2}";
5580     }
5582   [(set (attr "type")
5583      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5584         (const_string "incdec")
5585         (const_string "alu")))
5586    (set_attr "mode" "SI")])
5588 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5589 (define_insn "*addsi_2_zext"
5590   [(set (reg FLAGS_REG)
5591         (compare
5592           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5593                    (match_operand:SI 2 "general_operand" "rmni"))
5594           (const_int 0)))                       
5595    (set (match_operand:DI 0 "register_operand" "=r")
5596         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5597   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5598    && ix86_binary_operator_ok (PLUS, SImode, operands)
5599    /* Current assemblers are broken and do not allow @GOTOFF in
5600       ought but a memory context.  */
5601    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5603   switch (get_attr_type (insn))
5604     {
5605     case TYPE_INCDEC:
5606       if (operands[2] == const1_rtx)
5607         return "inc{l}\t%k0";
5608       else
5609         {
5610           gcc_assert (operands[2] == constm1_rtx);
5611           return "dec{l}\t%k0";
5612         }
5614     default:
5615       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5616          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5617       if (GET_CODE (operands[2]) == CONST_INT
5618           && (INTVAL (operands[2]) == 128
5619               || (INTVAL (operands[2]) < 0
5620                   && INTVAL (operands[2]) != -128)))
5621         {
5622           operands[2] = GEN_INT (-INTVAL (operands[2]));
5623           return "sub{l}\t{%2, %k0|%k0, %2}";
5624         }
5625       return "add{l}\t{%2, %k0|%k0, %2}";
5626     }
5628   [(set (attr "type")
5629      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5630         (const_string "incdec")
5631         (const_string "alu")))
5632    (set_attr "mode" "SI")])
5634 (define_insn "*addsi_3"
5635   [(set (reg FLAGS_REG)
5636         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5637                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5638    (clobber (match_scratch:SI 0 "=r"))]
5639   "ix86_match_ccmode (insn, CCZmode)
5640    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5641    /* Current assemblers are broken and do not allow @GOTOFF in
5642       ought but a memory context.  */
5643    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5645   switch (get_attr_type (insn))
5646     {
5647     case TYPE_INCDEC:
5648       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5649       if (operands[2] == const1_rtx)
5650         return "inc{l}\t%0";
5651       else
5652         {
5653           gcc_assert (operands[2] == constm1_rtx);
5654           return "dec{l}\t%0";
5655         }
5657     default:
5658       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5659       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5660          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5661       if (GET_CODE (operands[2]) == CONST_INT
5662           && (INTVAL (operands[2]) == 128
5663               || (INTVAL (operands[2]) < 0
5664                   && INTVAL (operands[2]) != -128)))
5665         {
5666           operands[2] = GEN_INT (-INTVAL (operands[2]));
5667           return "sub{l}\t{%2, %0|%0, %2}";
5668         }
5669       return "add{l}\t{%2, %0|%0, %2}";
5670     }
5672   [(set (attr "type")
5673      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674         (const_string "incdec")
5675         (const_string "alu")))
5676    (set_attr "mode" "SI")])
5678 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5679 (define_insn "*addsi_3_zext"
5680   [(set (reg FLAGS_REG)
5681         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5682                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5683    (set (match_operand:DI 0 "register_operand" "=r")
5684         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5685   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5686    && ix86_binary_operator_ok (PLUS, SImode, operands)
5687    /* Current assemblers are broken and do not allow @GOTOFF in
5688       ought but a memory context.  */
5689    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5691   switch (get_attr_type (insn))
5692     {
5693     case TYPE_INCDEC:
5694       if (operands[2] == const1_rtx)
5695         return "inc{l}\t%k0";
5696       else
5697         {
5698           gcc_assert (operands[2] == constm1_rtx);
5699           return "dec{l}\t%k0";
5700         }
5702     default:
5703       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5704          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5705       if (GET_CODE (operands[2]) == CONST_INT
5706           && (INTVAL (operands[2]) == 128
5707               || (INTVAL (operands[2]) < 0
5708                   && INTVAL (operands[2]) != -128)))
5709         {
5710           operands[2] = GEN_INT (-INTVAL (operands[2]));
5711           return "sub{l}\t{%2, %k0|%k0, %2}";
5712         }
5713       return "add{l}\t{%2, %k0|%k0, %2}";
5714     }
5716   [(set (attr "type")
5717      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5718         (const_string "incdec")
5719         (const_string "alu")))
5720    (set_attr "mode" "SI")])
5722 ; For comparisons against 1, -1 and 128, we may generate better code
5723 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5724 ; is matched then.  We can't accept general immediate, because for
5725 ; case of overflows,  the result is messed up.
5726 ; This pattern also don't hold of 0x80000000, since the value overflows
5727 ; when negated.
5728 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5729 ; only for comparisons not depending on it.
5730 (define_insn "*addsi_4"
5731   [(set (reg FLAGS_REG)
5732         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5733                  (match_operand:SI 2 "const_int_operand" "n")))
5734    (clobber (match_scratch:SI 0 "=rm"))]
5735   "ix86_match_ccmode (insn, CCGCmode)
5736    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5738   switch (get_attr_type (insn))
5739     {
5740     case TYPE_INCDEC:
5741       if (operands[2] == constm1_rtx)
5742         return "inc{l}\t%0";
5743       else
5744         {
5745           gcc_assert (operands[2] == const1_rtx);
5746           return "dec{l}\t%0";
5747         }
5749     default:
5750       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5751       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5752          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5753       if ((INTVAL (operands[2]) == -128
5754            || (INTVAL (operands[2]) > 0
5755                && INTVAL (operands[2]) != 128)))
5756         return "sub{l}\t{%2, %0|%0, %2}";
5757       operands[2] = GEN_INT (-INTVAL (operands[2]));
5758       return "add{l}\t{%2, %0|%0, %2}";
5759     }
5761   [(set (attr "type")
5762      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5763         (const_string "incdec")
5764         (const_string "alu")))
5765    (set_attr "mode" "SI")])
5767 (define_insn "*addsi_5"
5768   [(set (reg FLAGS_REG)
5769         (compare
5770           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5771                    (match_operand:SI 2 "general_operand" "rmni"))
5772           (const_int 0)))                       
5773    (clobber (match_scratch:SI 0 "=r"))]
5774   "ix86_match_ccmode (insn, CCGOCmode)
5775    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5776    /* Current assemblers are broken and do not allow @GOTOFF in
5777       ought but a memory context.  */
5778    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5780   switch (get_attr_type (insn))
5781     {
5782     case TYPE_INCDEC:
5783       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784       if (operands[2] == const1_rtx)
5785         return "inc{l}\t%0";
5786       else
5787         {
5788           gcc_assert (operands[2] == constm1_rtx);
5789           return "dec{l}\t%0";
5790         }
5792     default:
5793       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5794       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5795          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5796       if (GET_CODE (operands[2]) == CONST_INT
5797           && (INTVAL (operands[2]) == 128
5798               || (INTVAL (operands[2]) < 0
5799                   && INTVAL (operands[2]) != -128)))
5800         {
5801           operands[2] = GEN_INT (-INTVAL (operands[2]));
5802           return "sub{l}\t{%2, %0|%0, %2}";
5803         }
5804       return "add{l}\t{%2, %0|%0, %2}";
5805     }
5807   [(set (attr "type")
5808      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5809         (const_string "incdec")
5810         (const_string "alu")))
5811    (set_attr "mode" "SI")])
5813 (define_expand "addhi3"
5814   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5815                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5816                             (match_operand:HI 2 "general_operand" "")))
5817               (clobber (reg:CC FLAGS_REG))])]
5818   "TARGET_HIMODE_MATH"
5819   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5821 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5822 ;; type optimizations enabled by define-splits.  This is not important
5823 ;; for PII, and in fact harmful because of partial register stalls.
5825 (define_insn "*addhi_1_lea"
5826   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5827         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5828                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5829    (clobber (reg:CC FLAGS_REG))]
5830   "!TARGET_PARTIAL_REG_STALL
5831    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5833   switch (get_attr_type (insn))
5834     {
5835     case TYPE_LEA:
5836       return "#";
5837     case TYPE_INCDEC:
5838       if (operands[2] == const1_rtx)
5839         return "inc{w}\t%0";
5840       else
5841         {
5842           gcc_assert (operands[2] == constm1_rtx);
5843           return "dec{w}\t%0";
5844         }
5846     default:
5847       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5848          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5849       if (GET_CODE (operands[2]) == CONST_INT
5850           && (INTVAL (operands[2]) == 128
5851               || (INTVAL (operands[2]) < 0
5852                   && INTVAL (operands[2]) != -128)))
5853         {
5854           operands[2] = GEN_INT (-INTVAL (operands[2]));
5855           return "sub{w}\t{%2, %0|%0, %2}";
5856         }
5857       return "add{w}\t{%2, %0|%0, %2}";
5858     }
5860   [(set (attr "type")
5861      (if_then_else (eq_attr "alternative" "2")
5862         (const_string "lea")
5863         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5864            (const_string "incdec")
5865            (const_string "alu"))))
5866    (set_attr "mode" "HI,HI,SI")])
5868 (define_insn "*addhi_1"
5869   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5870         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5871                  (match_operand:HI 2 "general_operand" "ri,rm")))
5872    (clobber (reg:CC FLAGS_REG))]
5873   "TARGET_PARTIAL_REG_STALL
5874    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5876   switch (get_attr_type (insn))
5877     {
5878     case TYPE_INCDEC:
5879       if (operands[2] == const1_rtx)
5880         return "inc{w}\t%0";
5881       else
5882         {
5883           gcc_assert (operands[2] == constm1_rtx);
5884           return "dec{w}\t%0";
5885         }
5887     default:
5888       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5889          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5890       if (GET_CODE (operands[2]) == CONST_INT
5891           && (INTVAL (operands[2]) == 128
5892               || (INTVAL (operands[2]) < 0
5893                   && INTVAL (operands[2]) != -128)))
5894         {
5895           operands[2] = GEN_INT (-INTVAL (operands[2]));
5896           return "sub{w}\t{%2, %0|%0, %2}";
5897         }
5898       return "add{w}\t{%2, %0|%0, %2}";
5899     }
5901   [(set (attr "type")
5902      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5903         (const_string "incdec")
5904         (const_string "alu")))
5905    (set_attr "mode" "HI")])
5907 (define_insn "*addhi_2"
5908   [(set (reg FLAGS_REG)
5909         (compare
5910           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5911                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5912           (const_int 0)))                       
5913    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5914         (plus:HI (match_dup 1) (match_dup 2)))]
5915   "ix86_match_ccmode (insn, CCGOCmode)
5916    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5918   switch (get_attr_type (insn))
5919     {
5920     case TYPE_INCDEC:
5921       if (operands[2] == const1_rtx)
5922         return "inc{w}\t%0";
5923       else
5924         {
5925           gcc_assert (operands[2] == constm1_rtx);
5926           return "dec{w}\t%0";
5927         }
5929     default:
5930       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5931          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5932       if (GET_CODE (operands[2]) == CONST_INT
5933           && (INTVAL (operands[2]) == 128
5934               || (INTVAL (operands[2]) < 0
5935                   && INTVAL (operands[2]) != -128)))
5936         {
5937           operands[2] = GEN_INT (-INTVAL (operands[2]));
5938           return "sub{w}\t{%2, %0|%0, %2}";
5939         }
5940       return "add{w}\t{%2, %0|%0, %2}";
5941     }
5943   [(set (attr "type")
5944      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5945         (const_string "incdec")
5946         (const_string "alu")))
5947    (set_attr "mode" "HI")])
5949 (define_insn "*addhi_3"
5950   [(set (reg FLAGS_REG)
5951         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5952                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5953    (clobber (match_scratch:HI 0 "=r"))]
5954   "ix86_match_ccmode (insn, CCZmode)
5955    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5957   switch (get_attr_type (insn))
5958     {
5959     case TYPE_INCDEC:
5960       if (operands[2] == const1_rtx)
5961         return "inc{w}\t%0";
5962       else
5963         {
5964           gcc_assert (operands[2] == constm1_rtx);
5965           return "dec{w}\t%0";
5966         }
5968     default:
5969       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5970          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5971       if (GET_CODE (operands[2]) == CONST_INT
5972           && (INTVAL (operands[2]) == 128
5973               || (INTVAL (operands[2]) < 0
5974                   && INTVAL (operands[2]) != -128)))
5975         {
5976           operands[2] = GEN_INT (-INTVAL (operands[2]));
5977           return "sub{w}\t{%2, %0|%0, %2}";
5978         }
5979       return "add{w}\t{%2, %0|%0, %2}";
5980     }
5982   [(set (attr "type")
5983      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5984         (const_string "incdec")
5985         (const_string "alu")))
5986    (set_attr "mode" "HI")])
5988 ; See comments above addsi_4 for details.
5989 (define_insn "*addhi_4"
5990   [(set (reg FLAGS_REG)
5991         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5992                  (match_operand:HI 2 "const_int_operand" "n")))
5993    (clobber (match_scratch:HI 0 "=rm"))]
5994   "ix86_match_ccmode (insn, CCGCmode)
5995    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5997   switch (get_attr_type (insn))
5998     {
5999     case TYPE_INCDEC:
6000       if (operands[2] == constm1_rtx)
6001         return "inc{w}\t%0";
6002       else
6003         {
6004           gcc_assert (operands[2] == const1_rtx);
6005           return "dec{w}\t%0";
6006         }
6008     default:
6009       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6010       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6011          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6012       if ((INTVAL (operands[2]) == -128
6013            || (INTVAL (operands[2]) > 0
6014                && INTVAL (operands[2]) != 128)))
6015         return "sub{w}\t{%2, %0|%0, %2}";
6016       operands[2] = GEN_INT (-INTVAL (operands[2]));
6017       return "add{w}\t{%2, %0|%0, %2}";
6018     }
6020   [(set (attr "type")
6021      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6022         (const_string "incdec")
6023         (const_string "alu")))
6024    (set_attr "mode" "SI")])
6027 (define_insn "*addhi_5"
6028   [(set (reg FLAGS_REG)
6029         (compare
6030           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6031                    (match_operand:HI 2 "general_operand" "rmni"))
6032           (const_int 0)))                       
6033    (clobber (match_scratch:HI 0 "=r"))]
6034   "ix86_match_ccmode (insn, CCGOCmode)
6035    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6037   switch (get_attr_type (insn))
6038     {
6039     case TYPE_INCDEC:
6040       if (operands[2] == const1_rtx)
6041         return "inc{w}\t%0";
6042       else
6043         {
6044           gcc_assert (operands[2] == constm1_rtx);
6045           return "dec{w}\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           return "sub{w}\t{%2, %0|%0, %2}";
6058         }
6059       return "add{w}\t{%2, %0|%0, %2}";
6060     }
6062   [(set (attr "type")
6063      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6064         (const_string "incdec")
6065         (const_string "alu")))
6066    (set_attr "mode" "HI")])
6068 (define_expand "addqi3"
6069   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6070                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6071                             (match_operand:QI 2 "general_operand" "")))
6072               (clobber (reg:CC FLAGS_REG))])]
6073   "TARGET_QIMODE_MATH"
6074   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6076 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6077 (define_insn "*addqi_1_lea"
6078   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6079         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6080                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6081    (clobber (reg:CC FLAGS_REG))]
6082   "!TARGET_PARTIAL_REG_STALL
6083    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6085   int widen = (which_alternative == 2);
6086   switch (get_attr_type (insn))
6087     {
6088     case TYPE_LEA:
6089       return "#";
6090     case TYPE_INCDEC:
6091       if (operands[2] == const1_rtx)
6092         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6093       else
6094         {
6095           gcc_assert (operands[2] == constm1_rtx);
6096           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6097         }
6099     default:
6100       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6101          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6102       if (GET_CODE (operands[2]) == CONST_INT
6103           && (INTVAL (operands[2]) == 128
6104               || (INTVAL (operands[2]) < 0
6105                   && INTVAL (operands[2]) != -128)))
6106         {
6107           operands[2] = GEN_INT (-INTVAL (operands[2]));
6108           if (widen)
6109             return "sub{l}\t{%2, %k0|%k0, %2}";
6110           else
6111             return "sub{b}\t{%2, %0|%0, %2}";
6112         }
6113       if (widen)
6114         return "add{l}\t{%k2, %k0|%k0, %k2}";
6115       else
6116         return "add{b}\t{%2, %0|%0, %2}";
6117     }
6119   [(set (attr "type")
6120      (if_then_else (eq_attr "alternative" "3")
6121         (const_string "lea")
6122         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6123            (const_string "incdec")
6124            (const_string "alu"))))
6125    (set_attr "mode" "QI,QI,SI,SI")])
6127 (define_insn "*addqi_1"
6128   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6129         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6130                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6131    (clobber (reg:CC FLAGS_REG))]
6132   "TARGET_PARTIAL_REG_STALL
6133    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6135   int widen = (which_alternative == 2);
6136   switch (get_attr_type (insn))
6137     {
6138     case TYPE_INCDEC:
6139       if (operands[2] == const1_rtx)
6140         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6141       else
6142         {
6143           gcc_assert (operands[2] == constm1_rtx);
6144           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6145         }
6147     default:
6148       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6149          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6150       if (GET_CODE (operands[2]) == CONST_INT
6151           && (INTVAL (operands[2]) == 128
6152               || (INTVAL (operands[2]) < 0
6153                   && INTVAL (operands[2]) != -128)))
6154         {
6155           operands[2] = GEN_INT (-INTVAL (operands[2]));
6156           if (widen)
6157             return "sub{l}\t{%2, %k0|%k0, %2}";
6158           else
6159             return "sub{b}\t{%2, %0|%0, %2}";
6160         }
6161       if (widen)
6162         return "add{l}\t{%k2, %k0|%k0, %k2}";
6163       else
6164         return "add{b}\t{%2, %0|%0, %2}";
6165     }
6167   [(set (attr "type")
6168      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6169         (const_string "incdec")
6170         (const_string "alu")))
6171    (set_attr "mode" "QI,QI,SI")])
6173 (define_insn "*addqi_1_slp"
6174   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6175         (plus:QI (match_dup 0)
6176                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6177    (clobber (reg:CC FLAGS_REG))]
6178   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6179    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6181   switch (get_attr_type (insn))
6182     {
6183     case TYPE_INCDEC:
6184       if (operands[1] == const1_rtx)
6185         return "inc{b}\t%0";
6186       else
6187         {
6188           gcc_assert (operands[1] == constm1_rtx);
6189           return "dec{b}\t%0";
6190         }
6192     default:
6193       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6194       if (GET_CODE (operands[1]) == CONST_INT
6195           && INTVAL (operands[1]) < 0)
6196         {
6197           operands[1] = GEN_INT (-INTVAL (operands[1]));
6198           return "sub{b}\t{%1, %0|%0, %1}";
6199         }
6200       return "add{b}\t{%1, %0|%0, %1}";
6201     }
6203   [(set (attr "type")
6204      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6205         (const_string "incdec")
6206         (const_string "alu1")))
6207    (set (attr "memory")
6208      (if_then_else (match_operand 1 "memory_operand" "")
6209         (const_string "load")
6210         (const_string "none")))
6211    (set_attr "mode" "QI")])
6213 (define_insn "*addqi_2"
6214   [(set (reg FLAGS_REG)
6215         (compare
6216           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6217                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6218           (const_int 0)))
6219    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6220         (plus:QI (match_dup 1) (match_dup 2)))]
6221   "ix86_match_ccmode (insn, CCGOCmode)
6222    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6224   switch (get_attr_type (insn))
6225     {
6226     case TYPE_INCDEC:
6227       if (operands[2] == const1_rtx)
6228         return "inc{b}\t%0";
6229       else
6230         {
6231           gcc_assert (operands[2] == constm1_rtx
6232                       || (GET_CODE (operands[2]) == CONST_INT
6233                           && INTVAL (operands[2]) == 255));
6234           return "dec{b}\t%0";
6235         }
6237     default:
6238       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6239       if (GET_CODE (operands[2]) == CONST_INT
6240           && INTVAL (operands[2]) < 0)
6241         {
6242           operands[2] = GEN_INT (-INTVAL (operands[2]));
6243           return "sub{b}\t{%2, %0|%0, %2}";
6244         }
6245       return "add{b}\t{%2, %0|%0, %2}";
6246     }
6248   [(set (attr "type")
6249      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6250         (const_string "incdec")
6251         (const_string "alu")))
6252    (set_attr "mode" "QI")])
6254 (define_insn "*addqi_3"
6255   [(set (reg FLAGS_REG)
6256         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6257                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6258    (clobber (match_scratch:QI 0 "=q"))]
6259   "ix86_match_ccmode (insn, CCZmode)
6260    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6262   switch (get_attr_type (insn))
6263     {
6264     case TYPE_INCDEC:
6265       if (operands[2] == const1_rtx)
6266         return "inc{b}\t%0";
6267       else
6268         {
6269           gcc_assert (operands[2] == constm1_rtx
6270                       || (GET_CODE (operands[2]) == CONST_INT
6271                           && INTVAL (operands[2]) == 255));
6272           return "dec{b}\t%0";
6273         }
6275     default:
6276       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6277       if (GET_CODE (operands[2]) == CONST_INT
6278           && INTVAL (operands[2]) < 0)
6279         {
6280           operands[2] = GEN_INT (-INTVAL (operands[2]));
6281           return "sub{b}\t{%2, %0|%0, %2}";
6282         }
6283       return "add{b}\t{%2, %0|%0, %2}";
6284     }
6286   [(set (attr "type")
6287      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6288         (const_string "incdec")
6289         (const_string "alu")))
6290    (set_attr "mode" "QI")])
6292 ; See comments above addsi_4 for details.
6293 (define_insn "*addqi_4"
6294   [(set (reg FLAGS_REG)
6295         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6296                  (match_operand:QI 2 "const_int_operand" "n")))
6297    (clobber (match_scratch:QI 0 "=qm"))]
6298   "ix86_match_ccmode (insn, CCGCmode)
6299    && (INTVAL (operands[2]) & 0xff) != 0x80"
6301   switch (get_attr_type (insn))
6302     {
6303     case TYPE_INCDEC:
6304       if (operands[2] == constm1_rtx
6305           || (GET_CODE (operands[2]) == CONST_INT
6306               && INTVAL (operands[2]) == 255))
6307         return "inc{b}\t%0";
6308       else
6309         {
6310           gcc_assert (operands[2] == const1_rtx);
6311           return "dec{b}\t%0";
6312         }
6314     default:
6315       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6316       if (INTVAL (operands[2]) < 0)
6317         {
6318           operands[2] = GEN_INT (-INTVAL (operands[2]));
6319           return "add{b}\t{%2, %0|%0, %2}";
6320         }
6321       return "sub{b}\t{%2, %0|%0, %2}";
6322     }
6324   [(set (attr "type")
6325      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6326         (const_string "incdec")
6327         (const_string "alu")))
6328    (set_attr "mode" "QI")])
6331 (define_insn "*addqi_5"
6332   [(set (reg FLAGS_REG)
6333         (compare
6334           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6335                    (match_operand:QI 2 "general_operand" "qmni"))
6336           (const_int 0)))
6337    (clobber (match_scratch:QI 0 "=q"))]
6338   "ix86_match_ccmode (insn, CCGOCmode)
6339    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       if (operands[2] == const1_rtx)
6345         return "inc{b}\t%0";
6346       else
6347         {
6348           gcc_assert (operands[2] == constm1_rtx
6349                       || (GET_CODE (operands[2]) == CONST_INT
6350                           && INTVAL (operands[2]) == 255));
6351           return "dec{b}\t%0";
6352         }
6354     default:
6355       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6356       if (GET_CODE (operands[2]) == CONST_INT
6357           && INTVAL (operands[2]) < 0)
6358         {
6359           operands[2] = GEN_INT (-INTVAL (operands[2]));
6360           return "sub{b}\t{%2, %0|%0, %2}";
6361         }
6362       return "add{b}\t{%2, %0|%0, %2}";
6363     }
6365   [(set (attr "type")
6366      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6367         (const_string "incdec")
6368         (const_string "alu")))
6369    (set_attr "mode" "QI")])
6372 (define_insn "addqi_ext_1"
6373   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6374                          (const_int 8)
6375                          (const_int 8))
6376         (plus:SI
6377           (zero_extract:SI
6378             (match_operand 1 "ext_register_operand" "0")
6379             (const_int 8)
6380             (const_int 8))
6381           (match_operand:QI 2 "general_operand" "Qmn")))
6382    (clobber (reg:CC FLAGS_REG))]
6383   "!TARGET_64BIT"
6385   switch (get_attr_type (insn))
6386     {
6387     case TYPE_INCDEC:
6388       if (operands[2] == const1_rtx)
6389         return "inc{b}\t%h0";
6390       else
6391         {
6392           gcc_assert (operands[2] == constm1_rtx
6393                       || (GET_CODE (operands[2]) == CONST_INT
6394                           && INTVAL (operands[2]) == 255));
6395           return "dec{b}\t%h0";
6396         }
6398     default:
6399       return "add{b}\t{%2, %h0|%h0, %2}";
6400     }
6402   [(set (attr "type")
6403      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6404         (const_string "incdec")
6405         (const_string "alu")))
6406    (set_attr "mode" "QI")])
6408 (define_insn "*addqi_ext_1_rex64"
6409   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6410                          (const_int 8)
6411                          (const_int 8))
6412         (plus:SI
6413           (zero_extract:SI
6414             (match_operand 1 "ext_register_operand" "0")
6415             (const_int 8)
6416             (const_int 8))
6417           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6418    (clobber (reg:CC FLAGS_REG))]
6419   "TARGET_64BIT"
6421   switch (get_attr_type (insn))
6422     {
6423     case TYPE_INCDEC:
6424       if (operands[2] == const1_rtx)
6425         return "inc{b}\t%h0";
6426       else
6427         {
6428           gcc_assert (operands[2] == constm1_rtx
6429                       || (GET_CODE (operands[2]) == CONST_INT
6430                           && INTVAL (operands[2]) == 255));
6431           return "dec{b}\t%h0";
6432         }
6434     default:
6435       return "add{b}\t{%2, %h0|%h0, %2}";
6436     }
6438   [(set (attr "type")
6439      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6440         (const_string "incdec")
6441         (const_string "alu")))
6442    (set_attr "mode" "QI")])
6444 (define_insn "*addqi_ext_2"
6445   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6446                          (const_int 8)
6447                          (const_int 8))
6448         (plus:SI
6449           (zero_extract:SI
6450             (match_operand 1 "ext_register_operand" "%0")
6451             (const_int 8)
6452             (const_int 8))
6453           (zero_extract:SI
6454             (match_operand 2 "ext_register_operand" "Q")
6455             (const_int 8)
6456             (const_int 8))))
6457    (clobber (reg:CC FLAGS_REG))]
6458   ""
6459   "add{b}\t{%h2, %h0|%h0, %h2}"
6460   [(set_attr "type" "alu")
6461    (set_attr "mode" "QI")])
6463 ;; The patterns that match these are at the end of this file.
6465 (define_expand "addxf3"
6466   [(set (match_operand:XF 0 "register_operand" "")
6467         (plus:XF (match_operand:XF 1 "register_operand" "")
6468                  (match_operand:XF 2 "register_operand" "")))]
6469   "TARGET_80387"
6470   "")
6472 (define_expand "adddf3"
6473   [(set (match_operand:DF 0 "register_operand" "")
6474         (plus:DF (match_operand:DF 1 "register_operand" "")
6475                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6476   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6477   "")
6479 (define_expand "addsf3"
6480   [(set (match_operand:SF 0 "register_operand" "")
6481         (plus:SF (match_operand:SF 1 "register_operand" "")
6482                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6483   "TARGET_80387 || TARGET_SSE_MATH"
6484   "")
6486 ;; Subtract instructions
6488 ;; %%% splits for subditi3
6490 (define_expand "subti3"
6491   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6492                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6493                              (match_operand:TI 2 "x86_64_general_operand" "")))
6494               (clobber (reg:CC FLAGS_REG))])]
6495   "TARGET_64BIT"
6496   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6498 (define_insn "*subti3_1"
6499   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6500         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6501                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6502    (clobber (reg:CC FLAGS_REG))]
6503   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6504   "#")
6506 (define_split
6507   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6508         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6509                   (match_operand:TI 2 "general_operand" "")))
6510    (clobber (reg:CC FLAGS_REG))]
6511   "TARGET_64BIT && reload_completed"
6512   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6513               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6514    (parallel [(set (match_dup 3)
6515                    (minus:DI (match_dup 4)
6516                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6517                                       (match_dup 5))))
6518               (clobber (reg:CC FLAGS_REG))])]
6519   "split_ti (operands+0, 1, operands+0, operands+3);
6520    split_ti (operands+1, 1, operands+1, operands+4);
6521    split_ti (operands+2, 1, operands+2, operands+5);")
6523 ;; %%% splits for subsidi3
6525 (define_expand "subdi3"
6526   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6527                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6528                              (match_operand:DI 2 "x86_64_general_operand" "")))
6529               (clobber (reg:CC FLAGS_REG))])]
6530   ""
6531   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6533 (define_insn "*subdi3_1"
6534   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6535         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6536                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6537    (clobber (reg:CC FLAGS_REG))]
6538   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6539   "#")
6541 (define_split
6542   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6543         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6544                   (match_operand:DI 2 "general_operand" "")))
6545    (clobber (reg:CC FLAGS_REG))]
6546   "!TARGET_64BIT && reload_completed"
6547   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6548               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6549    (parallel [(set (match_dup 3)
6550                    (minus:SI (match_dup 4)
6551                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6552                                       (match_dup 5))))
6553               (clobber (reg:CC FLAGS_REG))])]
6554   "split_di (operands+0, 1, operands+0, operands+3);
6555    split_di (operands+1, 1, operands+1, operands+4);
6556    split_di (operands+2, 1, operands+2, operands+5);")
6558 (define_insn "subdi3_carry_rex64"
6559   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6560           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6561             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6562                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6563    (clobber (reg:CC FLAGS_REG))]
6564   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6565   "sbb{q}\t{%2, %0|%0, %2}"
6566   [(set_attr "type" "alu")
6567    (set_attr "pent_pair" "pu")
6568    (set_attr "mode" "DI")])
6570 (define_insn "*subdi_1_rex64"
6571   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6572         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6573                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6574    (clobber (reg:CC FLAGS_REG))]
6575   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6576   "sub{q}\t{%2, %0|%0, %2}"
6577   [(set_attr "type" "alu")
6578    (set_attr "mode" "DI")])
6580 (define_insn "*subdi_2_rex64"
6581   [(set (reg FLAGS_REG)
6582         (compare
6583           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6584                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6585           (const_int 0)))
6586    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6587         (minus:DI (match_dup 1) (match_dup 2)))]
6588   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6589    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6590   "sub{q}\t{%2, %0|%0, %2}"
6591   [(set_attr "type" "alu")
6592    (set_attr "mode" "DI")])
6594 (define_insn "*subdi_3_rex63"
6595   [(set (reg FLAGS_REG)
6596         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6597                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6598    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6599         (minus:DI (match_dup 1) (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_insn "subqi3_carry"
6607   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6608           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6609             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6610                (match_operand:QI 2 "general_operand" "qi,qm"))))
6611    (clobber (reg:CC FLAGS_REG))]
6612   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6613   "sbb{b}\t{%2, %0|%0, %2}"
6614   [(set_attr "type" "alu")
6615    (set_attr "pent_pair" "pu")
6616    (set_attr "mode" "QI")])
6618 (define_insn "subhi3_carry"
6619   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6620           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6621             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6622                (match_operand:HI 2 "general_operand" "ri,rm"))))
6623    (clobber (reg:CC FLAGS_REG))]
6624   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6625   "sbb{w}\t{%2, %0|%0, %2}"
6626   [(set_attr "type" "alu")
6627    (set_attr "pent_pair" "pu")
6628    (set_attr "mode" "HI")])
6630 (define_insn "subsi3_carry"
6631   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6632           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6633             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6634                (match_operand:SI 2 "general_operand" "ri,rm"))))
6635    (clobber (reg:CC FLAGS_REG))]
6636   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6637   "sbb{l}\t{%2, %0|%0, %2}"
6638   [(set_attr "type" "alu")
6639    (set_attr "pent_pair" "pu")
6640    (set_attr "mode" "SI")])
6642 (define_insn "subsi3_carry_zext"
6643   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6644           (zero_extend:DI
6645             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6646               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6647                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6648    (clobber (reg:CC FLAGS_REG))]
6649   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6650   "sbb{l}\t{%2, %k0|%k0, %2}"
6651   [(set_attr "type" "alu")
6652    (set_attr "pent_pair" "pu")
6653    (set_attr "mode" "SI")])
6655 (define_expand "subsi3"
6656   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6657                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6658                              (match_operand:SI 2 "general_operand" "")))
6659               (clobber (reg:CC FLAGS_REG))])]
6660   ""
6661   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6663 (define_insn "*subsi_1"
6664   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6665         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6666                   (match_operand:SI 2 "general_operand" "ri,rm")))
6667    (clobber (reg:CC FLAGS_REG))]
6668   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6669   "sub{l}\t{%2, %0|%0, %2}"
6670   [(set_attr "type" "alu")
6671    (set_attr "mode" "SI")])
6673 (define_insn "*subsi_1_zext"
6674   [(set (match_operand:DI 0 "register_operand" "=r")
6675         (zero_extend:DI
6676           (minus:SI (match_operand:SI 1 "register_operand" "0")
6677                     (match_operand:SI 2 "general_operand" "rim"))))
6678    (clobber (reg:CC FLAGS_REG))]
6679   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6680   "sub{l}\t{%2, %k0|%k0, %2}"
6681   [(set_attr "type" "alu")
6682    (set_attr "mode" "SI")])
6684 (define_insn "*subsi_2"
6685   [(set (reg FLAGS_REG)
6686         (compare
6687           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6688                     (match_operand:SI 2 "general_operand" "ri,rm"))
6689           (const_int 0)))
6690    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6691         (minus:SI (match_dup 1) (match_dup 2)))]
6692   "ix86_match_ccmode (insn, CCGOCmode)
6693    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6694   "sub{l}\t{%2, %0|%0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "mode" "SI")])
6698 (define_insn "*subsi_2_zext"
6699   [(set (reg FLAGS_REG)
6700         (compare
6701           (minus:SI (match_operand:SI 1 "register_operand" "0")
6702                     (match_operand:SI 2 "general_operand" "rim"))
6703           (const_int 0)))
6704    (set (match_operand:DI 0 "register_operand" "=r")
6705         (zero_extend:DI
6706           (minus:SI (match_dup 1)
6707                     (match_dup 2))))]
6708   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6709    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6710   "sub{l}\t{%2, %k0|%k0, %2}"
6711   [(set_attr "type" "alu")
6712    (set_attr "mode" "SI")])
6714 (define_insn "*subsi_3"
6715   [(set (reg FLAGS_REG)
6716         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6717                  (match_operand:SI 2 "general_operand" "ri,rm")))
6718    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6719         (minus:SI (match_dup 1) (match_dup 2)))]
6720   "ix86_match_ccmode (insn, CCmode)
6721    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6722   "sub{l}\t{%2, %0|%0, %2}"
6723   [(set_attr "type" "alu")
6724    (set_attr "mode" "SI")])
6726 (define_insn "*subsi_3_zext"
6727   [(set (reg FLAGS_REG)
6728         (compare (match_operand:SI 1 "register_operand" "0")
6729                  (match_operand:SI 2 "general_operand" "rim")))
6730    (set (match_operand:DI 0 "register_operand" "=r")
6731         (zero_extend:DI
6732           (minus:SI (match_dup 1)
6733                     (match_dup 2))))]
6734   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6735    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6736   "sub{l}\t{%2, %1|%1, %2}"
6737   [(set_attr "type" "alu")
6738    (set_attr "mode" "DI")])
6740 (define_expand "subhi3"
6741   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6742                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6743                              (match_operand:HI 2 "general_operand" "")))
6744               (clobber (reg:CC FLAGS_REG))])]
6745   "TARGET_HIMODE_MATH"
6746   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6748 (define_insn "*subhi_1"
6749   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6750         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6751                   (match_operand:HI 2 "general_operand" "ri,rm")))
6752    (clobber (reg:CC FLAGS_REG))]
6753   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6754   "sub{w}\t{%2, %0|%0, %2}"
6755   [(set_attr "type" "alu")
6756    (set_attr "mode" "HI")])
6758 (define_insn "*subhi_2"
6759   [(set (reg FLAGS_REG)
6760         (compare
6761           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6762                     (match_operand:HI 2 "general_operand" "ri,rm"))
6763           (const_int 0)))
6764    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6765         (minus:HI (match_dup 1) (match_dup 2)))]
6766   "ix86_match_ccmode (insn, CCGOCmode)
6767    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6768   "sub{w}\t{%2, %0|%0, %2}"
6769   [(set_attr "type" "alu")
6770    (set_attr "mode" "HI")])
6772 (define_insn "*subhi_3"
6773   [(set (reg FLAGS_REG)
6774         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6775                  (match_operand:HI 2 "general_operand" "ri,rm")))
6776    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6777         (minus:HI (match_dup 1) (match_dup 2)))]
6778   "ix86_match_ccmode (insn, CCmode)
6779    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6780   "sub{w}\t{%2, %0|%0, %2}"
6781   [(set_attr "type" "alu")
6782    (set_attr "mode" "HI")])
6784 (define_expand "subqi3"
6785   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6786                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6787                              (match_operand:QI 2 "general_operand" "")))
6788               (clobber (reg:CC FLAGS_REG))])]
6789   "TARGET_QIMODE_MATH"
6790   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6792 (define_insn "*subqi_1"
6793   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6794         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6795                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6796    (clobber (reg:CC FLAGS_REG))]
6797   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6798   "sub{b}\t{%2, %0|%0, %2}"
6799   [(set_attr "type" "alu")
6800    (set_attr "mode" "QI")])
6802 (define_insn "*subqi_1_slp"
6803   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6804         (minus:QI (match_dup 0)
6805                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6806    (clobber (reg:CC FLAGS_REG))]
6807   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6808    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6809   "sub{b}\t{%1, %0|%0, %1}"
6810   [(set_attr "type" "alu1")
6811    (set_attr "mode" "QI")])
6813 (define_insn "*subqi_2"
6814   [(set (reg FLAGS_REG)
6815         (compare
6816           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6817                     (match_operand:QI 2 "general_operand" "qi,qm"))
6818           (const_int 0)))
6819    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6820         (minus:HI (match_dup 1) (match_dup 2)))]
6821   "ix86_match_ccmode (insn, CCGOCmode)
6822    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6823   "sub{b}\t{%2, %0|%0, %2}"
6824   [(set_attr "type" "alu")
6825    (set_attr "mode" "QI")])
6827 (define_insn "*subqi_3"
6828   [(set (reg FLAGS_REG)
6829         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6830                  (match_operand:QI 2 "general_operand" "qi,qm")))
6831    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6832         (minus:HI (match_dup 1) (match_dup 2)))]
6833   "ix86_match_ccmode (insn, CCmode)
6834    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6835   "sub{b}\t{%2, %0|%0, %2}"
6836   [(set_attr "type" "alu")
6837    (set_attr "mode" "QI")])
6839 ;; The patterns that match these are at the end of this file.
6841 (define_expand "subxf3"
6842   [(set (match_operand:XF 0 "register_operand" "")
6843         (minus:XF (match_operand:XF 1 "register_operand" "")
6844                   (match_operand:XF 2 "register_operand" "")))]
6845   "TARGET_80387"
6846   "")
6848 (define_expand "subdf3"
6849   [(set (match_operand:DF 0 "register_operand" "")
6850         (minus:DF (match_operand:DF 1 "register_operand" "")
6851                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6852   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6853   "")
6855 (define_expand "subsf3"
6856   [(set (match_operand:SF 0 "register_operand" "")
6857         (minus:SF (match_operand:SF 1 "register_operand" "")
6858                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6859   "TARGET_80387 || TARGET_SSE_MATH"
6860   "")
6862 ;; Multiply instructions
6864 (define_expand "muldi3"
6865   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6866                    (mult:DI (match_operand:DI 1 "register_operand" "")
6867                             (match_operand:DI 2 "x86_64_general_operand" "")))
6868               (clobber (reg:CC FLAGS_REG))])]
6869   "TARGET_64BIT"
6870   "")
6872 (define_insn "*muldi3_1_rex64"
6873   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6874         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6875                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6876    (clobber (reg:CC FLAGS_REG))]
6877   "TARGET_64BIT
6878    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6879   "@
6880    imul{q}\t{%2, %1, %0|%0, %1, %2}
6881    imul{q}\t{%2, %1, %0|%0, %1, %2}
6882    imul{q}\t{%2, %0|%0, %2}"
6883   [(set_attr "type" "imul")
6884    (set_attr "prefix_0f" "0,0,1")
6885    (set (attr "athlon_decode")
6886         (cond [(eq_attr "cpu" "athlon")
6887                   (const_string "vector")
6888                (eq_attr "alternative" "1")
6889                   (const_string "vector")
6890                (and (eq_attr "alternative" "2")
6891                     (match_operand 1 "memory_operand" ""))
6892                   (const_string "vector")]
6893               (const_string "direct")))
6894    (set_attr "mode" "DI")])
6896 (define_expand "mulsi3"
6897   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6898                    (mult:SI (match_operand:SI 1 "register_operand" "")
6899                             (match_operand:SI 2 "general_operand" "")))
6900               (clobber (reg:CC FLAGS_REG))])]
6901   ""
6902   "")
6904 (define_insn "*mulsi3_1"
6905   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6906         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6907                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6908    (clobber (reg:CC FLAGS_REG))]
6909   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6910   "@
6911    imul{l}\t{%2, %1, %0|%0, %1, %2}
6912    imul{l}\t{%2, %1, %0|%0, %1, %2}
6913    imul{l}\t{%2, %0|%0, %2}"
6914   [(set_attr "type" "imul")
6915    (set_attr "prefix_0f" "0,0,1")
6916    (set (attr "athlon_decode")
6917         (cond [(eq_attr "cpu" "athlon")
6918                   (const_string "vector")
6919                (eq_attr "alternative" "1")
6920                   (const_string "vector")
6921                (and (eq_attr "alternative" "2")
6922                     (match_operand 1 "memory_operand" ""))
6923                   (const_string "vector")]
6924               (const_string "direct")))
6925    (set_attr "mode" "SI")])
6927 (define_insn "*mulsi3_1_zext"
6928   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6929         (zero_extend:DI
6930           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6931                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6932    (clobber (reg:CC FLAGS_REG))]
6933   "TARGET_64BIT
6934    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6935   "@
6936    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6937    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6938    imul{l}\t{%2, %k0|%k0, %2}"
6939   [(set_attr "type" "imul")
6940    (set_attr "prefix_0f" "0,0,1")
6941    (set (attr "athlon_decode")
6942         (cond [(eq_attr "cpu" "athlon")
6943                   (const_string "vector")
6944                (eq_attr "alternative" "1")
6945                   (const_string "vector")
6946                (and (eq_attr "alternative" "2")
6947                     (match_operand 1 "memory_operand" ""))
6948                   (const_string "vector")]
6949               (const_string "direct")))
6950    (set_attr "mode" "SI")])
6952 (define_expand "mulhi3"
6953   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6954                    (mult:HI (match_operand:HI 1 "register_operand" "")
6955                             (match_operand:HI 2 "general_operand" "")))
6956               (clobber (reg:CC FLAGS_REG))])]
6957   "TARGET_HIMODE_MATH"
6958   "")
6960 (define_insn "*mulhi3_1"
6961   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6962         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6963                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6964    (clobber (reg:CC FLAGS_REG))]
6965   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6966   "@
6967    imul{w}\t{%2, %1, %0|%0, %1, %2}
6968    imul{w}\t{%2, %1, %0|%0, %1, %2}
6969    imul{w}\t{%2, %0|%0, %2}"
6970   [(set_attr "type" "imul")
6971    (set_attr "prefix_0f" "0,0,1")
6972    (set (attr "athlon_decode")
6973         (cond [(eq_attr "cpu" "athlon")
6974                   (const_string "vector")
6975                (eq_attr "alternative" "1,2")
6976                   (const_string "vector")]
6977               (const_string "direct")))
6978    (set_attr "mode" "HI")])
6980 (define_expand "mulqi3"
6981   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6982                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6983                             (match_operand:QI 2 "register_operand" "")))
6984               (clobber (reg:CC FLAGS_REG))])]
6985   "TARGET_QIMODE_MATH"
6986   "")
6988 (define_insn "*mulqi3_1"
6989   [(set (match_operand:QI 0 "register_operand" "=a")
6990         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6991                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6992    (clobber (reg:CC FLAGS_REG))]
6993   "TARGET_QIMODE_MATH
6994    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6995   "mul{b}\t%2"
6996   [(set_attr "type" "imul")
6997    (set_attr "length_immediate" "0")
6998    (set (attr "athlon_decode")
6999      (if_then_else (eq_attr "cpu" "athlon")
7000         (const_string "vector")
7001         (const_string "direct")))
7002    (set_attr "mode" "QI")])
7004 (define_expand "umulqihi3"
7005   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7006                    (mult:HI (zero_extend:HI
7007                               (match_operand:QI 1 "nonimmediate_operand" ""))
7008                             (zero_extend:HI
7009                               (match_operand:QI 2 "register_operand" ""))))
7010               (clobber (reg:CC FLAGS_REG))])]
7011   "TARGET_QIMODE_MATH"
7012   "")
7014 (define_insn "*umulqihi3_1"
7015   [(set (match_operand:HI 0 "register_operand" "=a")
7016         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7017                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7018    (clobber (reg:CC FLAGS_REG))]
7019   "TARGET_QIMODE_MATH
7020    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7021   "mul{b}\t%2"
7022   [(set_attr "type" "imul")
7023    (set_attr "length_immediate" "0")
7024    (set (attr "athlon_decode")
7025      (if_then_else (eq_attr "cpu" "athlon")
7026         (const_string "vector")
7027         (const_string "direct")))
7028    (set_attr "mode" "QI")])
7030 (define_expand "mulqihi3"
7031   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7032                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7033                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7034               (clobber (reg:CC FLAGS_REG))])]
7035   "TARGET_QIMODE_MATH"
7036   "")
7038 (define_insn "*mulqihi3_insn"
7039   [(set (match_operand:HI 0 "register_operand" "=a")
7040         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7041                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7042    (clobber (reg:CC FLAGS_REG))]
7043   "TARGET_QIMODE_MATH
7044    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7045   "imul{b}\t%2"
7046   [(set_attr "type" "imul")
7047    (set_attr "length_immediate" "0")
7048    (set (attr "athlon_decode")
7049      (if_then_else (eq_attr "cpu" "athlon")
7050         (const_string "vector")
7051         (const_string "direct")))
7052    (set_attr "mode" "QI")])
7054 (define_expand "umulditi3"
7055   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7056                    (mult:TI (zero_extend:TI
7057                               (match_operand:DI 1 "nonimmediate_operand" ""))
7058                             (zero_extend:TI
7059                               (match_operand:DI 2 "register_operand" ""))))
7060               (clobber (reg:CC FLAGS_REG))])]
7061   "TARGET_64BIT"
7062   "")
7064 (define_insn "*umulditi3_insn"
7065   [(set (match_operand:TI 0 "register_operand" "=A")
7066         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7067                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7068    (clobber (reg:CC FLAGS_REG))]
7069   "TARGET_64BIT
7070    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7071   "mul{q}\t%2"
7072   [(set_attr "type" "imul")
7073    (set_attr "length_immediate" "0")
7074    (set (attr "athlon_decode")
7075      (if_then_else (eq_attr "cpu" "athlon")
7076         (const_string "vector")
7077         (const_string "double")))
7078    (set_attr "mode" "DI")])
7080 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7081 (define_expand "umulsidi3"
7082   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7083                    (mult:DI (zero_extend:DI
7084                               (match_operand:SI 1 "nonimmediate_operand" ""))
7085                             (zero_extend:DI
7086                               (match_operand:SI 2 "register_operand" ""))))
7087               (clobber (reg:CC FLAGS_REG))])]
7088   "!TARGET_64BIT"
7089   "")
7091 (define_insn "*umulsidi3_insn"
7092   [(set (match_operand:DI 0 "register_operand" "=A")
7093         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7094                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7095    (clobber (reg:CC FLAGS_REG))]
7096   "!TARGET_64BIT
7097    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7098   "mul{l}\t%2"
7099   [(set_attr "type" "imul")
7100    (set_attr "length_immediate" "0")
7101    (set (attr "athlon_decode")
7102      (if_then_else (eq_attr "cpu" "athlon")
7103         (const_string "vector")
7104         (const_string "double")))
7105    (set_attr "mode" "SI")])
7107 (define_expand "mulditi3"
7108   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7109                    (mult:TI (sign_extend:TI
7110                               (match_operand:DI 1 "nonimmediate_operand" ""))
7111                             (sign_extend:TI
7112                               (match_operand:DI 2 "register_operand" ""))))
7113               (clobber (reg:CC FLAGS_REG))])]
7114   "TARGET_64BIT"
7115   "")
7117 (define_insn "*mulditi3_insn"
7118   [(set (match_operand:TI 0 "register_operand" "=A")
7119         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7120                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7121    (clobber (reg:CC FLAGS_REG))]
7122   "TARGET_64BIT
7123    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7124   "imul{q}\t%2"
7125   [(set_attr "type" "imul")
7126    (set_attr "length_immediate" "0")
7127    (set (attr "athlon_decode")
7128      (if_then_else (eq_attr "cpu" "athlon")
7129         (const_string "vector")
7130         (const_string "double")))
7131    (set_attr "mode" "DI")])
7133 (define_expand "mulsidi3"
7134   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7135                    (mult:DI (sign_extend:DI
7136                               (match_operand:SI 1 "nonimmediate_operand" ""))
7137                             (sign_extend:DI
7138                               (match_operand:SI 2 "register_operand" ""))))
7139               (clobber (reg:CC FLAGS_REG))])]
7140   "!TARGET_64BIT"
7141   "")
7143 (define_insn "*mulsidi3_insn"
7144   [(set (match_operand:DI 0 "register_operand" "=A")
7145         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7146                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7147    (clobber (reg:CC FLAGS_REG))]
7148   "!TARGET_64BIT
7149    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7150   "imul{l}\t%2"
7151   [(set_attr "type" "imul")
7152    (set_attr "length_immediate" "0")
7153    (set (attr "athlon_decode")
7154      (if_then_else (eq_attr "cpu" "athlon")
7155         (const_string "vector")
7156         (const_string "double")))
7157    (set_attr "mode" "SI")])
7159 (define_expand "umuldi3_highpart"
7160   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7161                    (truncate:DI
7162                      (lshiftrt:TI
7163                        (mult:TI (zero_extend:TI
7164                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7165                                 (zero_extend:TI
7166                                   (match_operand:DI 2 "register_operand" "")))
7167                        (const_int 64))))
7168               (clobber (match_scratch:DI 3 ""))
7169               (clobber (reg:CC FLAGS_REG))])]
7170   "TARGET_64BIT"
7171   "")
7173 (define_insn "*umuldi3_highpart_rex64"
7174   [(set (match_operand:DI 0 "register_operand" "=d")
7175         (truncate:DI
7176           (lshiftrt:TI
7177             (mult:TI (zero_extend:TI
7178                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7179                      (zero_extend:TI
7180                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7181             (const_int 64))))
7182    (clobber (match_scratch:DI 3 "=1"))
7183    (clobber (reg:CC FLAGS_REG))]
7184   "TARGET_64BIT
7185    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7186   "mul{q}\t%2"
7187   [(set_attr "type" "imul")
7188    (set_attr "length_immediate" "0")
7189    (set (attr "athlon_decode")
7190      (if_then_else (eq_attr "cpu" "athlon")
7191         (const_string "vector")
7192         (const_string "double")))
7193    (set_attr "mode" "DI")])
7195 (define_expand "umulsi3_highpart"
7196   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7197                    (truncate:SI
7198                      (lshiftrt:DI
7199                        (mult:DI (zero_extend:DI
7200                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7201                                 (zero_extend:DI
7202                                   (match_operand:SI 2 "register_operand" "")))
7203                        (const_int 32))))
7204               (clobber (match_scratch:SI 3 ""))
7205               (clobber (reg:CC FLAGS_REG))])]
7206   ""
7207   "")
7209 (define_insn "*umulsi3_highpart_insn"
7210   [(set (match_operand:SI 0 "register_operand" "=d")
7211         (truncate:SI
7212           (lshiftrt:DI
7213             (mult:DI (zero_extend:DI
7214                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7215                      (zero_extend:DI
7216                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7217             (const_int 32))))
7218    (clobber (match_scratch:SI 3 "=1"))
7219    (clobber (reg:CC FLAGS_REG))]
7220   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7221   "mul{l}\t%2"
7222   [(set_attr "type" "imul")
7223    (set_attr "length_immediate" "0")
7224    (set (attr "athlon_decode")
7225      (if_then_else (eq_attr "cpu" "athlon")
7226         (const_string "vector")
7227         (const_string "double")))
7228    (set_attr "mode" "SI")])
7230 (define_insn "*umulsi3_highpart_zext"
7231   [(set (match_operand:DI 0 "register_operand" "=d")
7232         (zero_extend:DI (truncate:SI
7233           (lshiftrt:DI
7234             (mult:DI (zero_extend:DI
7235                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7236                      (zero_extend:DI
7237                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7238             (const_int 32)))))
7239    (clobber (match_scratch:SI 3 "=1"))
7240    (clobber (reg:CC FLAGS_REG))]
7241   "TARGET_64BIT
7242    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7243   "mul{l}\t%2"
7244   [(set_attr "type" "imul")
7245    (set_attr "length_immediate" "0")
7246    (set (attr "athlon_decode")
7247      (if_then_else (eq_attr "cpu" "athlon")
7248         (const_string "vector")
7249         (const_string "double")))
7250    (set_attr "mode" "SI")])
7252 (define_expand "smuldi3_highpart"
7253   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7254                    (truncate:DI
7255                      (lshiftrt:TI
7256                        (mult:TI (sign_extend:TI
7257                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7258                                 (sign_extend:TI
7259                                   (match_operand:DI 2 "register_operand" "")))
7260                        (const_int 64))))
7261               (clobber (match_scratch:DI 3 ""))
7262               (clobber (reg:CC FLAGS_REG))])]
7263   "TARGET_64BIT"
7264   "")
7266 (define_insn "*smuldi3_highpart_rex64"
7267   [(set (match_operand:DI 0 "register_operand" "=d")
7268         (truncate:DI
7269           (lshiftrt:TI
7270             (mult:TI (sign_extend:TI
7271                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7272                      (sign_extend:TI
7273                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7274             (const_int 64))))
7275    (clobber (match_scratch:DI 3 "=1"))
7276    (clobber (reg:CC FLAGS_REG))]
7277   "TARGET_64BIT
7278    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7279   "imul{q}\t%2"
7280   [(set_attr "type" "imul")
7281    (set (attr "athlon_decode")
7282      (if_then_else (eq_attr "cpu" "athlon")
7283         (const_string "vector")
7284         (const_string "double")))
7285    (set_attr "mode" "DI")])
7287 (define_expand "smulsi3_highpart"
7288   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7289                    (truncate:SI
7290                      (lshiftrt:DI
7291                        (mult:DI (sign_extend:DI
7292                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7293                                 (sign_extend:DI
7294                                   (match_operand:SI 2 "register_operand" "")))
7295                        (const_int 32))))
7296               (clobber (match_scratch:SI 3 ""))
7297               (clobber (reg:CC FLAGS_REG))])]
7298   ""
7299   "")
7301 (define_insn "*smulsi3_highpart_insn"
7302   [(set (match_operand:SI 0 "register_operand" "=d")
7303         (truncate:SI
7304           (lshiftrt:DI
7305             (mult:DI (sign_extend:DI
7306                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7307                      (sign_extend:DI
7308                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7309             (const_int 32))))
7310    (clobber (match_scratch:SI 3 "=1"))
7311    (clobber (reg:CC FLAGS_REG))]
7312   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7313   "imul{l}\t%2"
7314   [(set_attr "type" "imul")
7315    (set (attr "athlon_decode")
7316      (if_then_else (eq_attr "cpu" "athlon")
7317         (const_string "vector")
7318         (const_string "double")))
7319    (set_attr "mode" "SI")])
7321 (define_insn "*smulsi3_highpart_zext"
7322   [(set (match_operand:DI 0 "register_operand" "=d")
7323         (zero_extend:DI (truncate:SI
7324           (lshiftrt:DI
7325             (mult:DI (sign_extend:DI
7326                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7327                      (sign_extend:DI
7328                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7329             (const_int 32)))))
7330    (clobber (match_scratch:SI 3 "=1"))
7331    (clobber (reg:CC FLAGS_REG))]
7332   "TARGET_64BIT
7333    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7334   "imul{l}\t%2"
7335   [(set_attr "type" "imul")
7336    (set (attr "athlon_decode")
7337      (if_then_else (eq_attr "cpu" "athlon")
7338         (const_string "vector")
7339         (const_string "double")))
7340    (set_attr "mode" "SI")])
7342 ;; The patterns that match these are at the end of this file.
7344 (define_expand "mulxf3"
7345   [(set (match_operand:XF 0 "register_operand" "")
7346         (mult:XF (match_operand:XF 1 "register_operand" "")
7347                  (match_operand:XF 2 "register_operand" "")))]
7348   "TARGET_80387"
7349   "")
7351 (define_expand "muldf3"
7352   [(set (match_operand:DF 0 "register_operand" "")
7353         (mult:DF (match_operand:DF 1 "register_operand" "")
7354                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7355   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7356   "")
7358 (define_expand "mulsf3"
7359   [(set (match_operand:SF 0 "register_operand" "")
7360         (mult:SF (match_operand:SF 1 "register_operand" "")
7361                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7362   "TARGET_80387 || TARGET_SSE_MATH"
7363   "")
7365 ;; Divide instructions
7367 (define_insn "divqi3"
7368   [(set (match_operand:QI 0 "register_operand" "=a")
7369         (div:QI (match_operand:HI 1 "register_operand" "0")
7370                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7371    (clobber (reg:CC FLAGS_REG))]
7372   "TARGET_QIMODE_MATH"
7373   "idiv{b}\t%2"
7374   [(set_attr "type" "idiv")
7375    (set_attr "mode" "QI")])
7377 (define_insn "udivqi3"
7378   [(set (match_operand:QI 0 "register_operand" "=a")
7379         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7380                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7381    (clobber (reg:CC FLAGS_REG))]
7382   "TARGET_QIMODE_MATH"
7383   "div{b}\t%2"
7384   [(set_attr "type" "idiv")
7385    (set_attr "mode" "QI")])
7387 ;; The patterns that match these are at the end of this file.
7389 (define_expand "divxf3"
7390   [(set (match_operand:XF 0 "register_operand" "")
7391         (div:XF (match_operand:XF 1 "register_operand" "")
7392                 (match_operand:XF 2 "register_operand" "")))]
7393   "TARGET_80387"
7394   "")
7396 (define_expand "divdf3"
7397   [(set (match_operand:DF 0 "register_operand" "")
7398         (div:DF (match_operand:DF 1 "register_operand" "")
7399                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7400    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7401    "")
7403 (define_expand "divsf3"
7404   [(set (match_operand:SF 0 "register_operand" "")
7405         (div:SF (match_operand:SF 1 "register_operand" "")
7406                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7407   "TARGET_80387 || TARGET_SSE_MATH"
7408   "")
7410 ;; Remainder instructions.
7412 (define_expand "divmoddi4"
7413   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7414                    (div:DI (match_operand:DI 1 "register_operand" "")
7415                            (match_operand:DI 2 "nonimmediate_operand" "")))
7416               (set (match_operand:DI 3 "register_operand" "")
7417                    (mod:DI (match_dup 1) (match_dup 2)))
7418               (clobber (reg:CC FLAGS_REG))])]
7419   "TARGET_64BIT"
7420   "")
7422 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7423 ;; Penalize eax case slightly because it results in worse scheduling
7424 ;; of code.
7425 (define_insn "*divmoddi4_nocltd_rex64"
7426   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7427         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7428                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7429    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7430         (mod:DI (match_dup 2) (match_dup 3)))
7431    (clobber (reg:CC FLAGS_REG))]
7432   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7433   "#"
7434   [(set_attr "type" "multi")])
7436 (define_insn "*divmoddi4_cltd_rex64"
7437   [(set (match_operand:DI 0 "register_operand" "=a")
7438         (div:DI (match_operand:DI 2 "register_operand" "a")
7439                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7440    (set (match_operand:DI 1 "register_operand" "=&d")
7441         (mod:DI (match_dup 2) (match_dup 3)))
7442    (clobber (reg:CC FLAGS_REG))]
7443   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7444   "#"
7445   [(set_attr "type" "multi")])
7447 (define_insn "*divmoddi_noext_rex64"
7448   [(set (match_operand:DI 0 "register_operand" "=a")
7449         (div:DI (match_operand:DI 1 "register_operand" "0")
7450                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7451    (set (match_operand:DI 3 "register_operand" "=d")
7452         (mod:DI (match_dup 1) (match_dup 2)))
7453    (use (match_operand:DI 4 "register_operand" "3"))
7454    (clobber (reg:CC FLAGS_REG))]
7455   "TARGET_64BIT"
7456   "idiv{q}\t%2"
7457   [(set_attr "type" "idiv")
7458    (set_attr "mode" "DI")])
7460 (define_split
7461   [(set (match_operand:DI 0 "register_operand" "")
7462         (div:DI (match_operand:DI 1 "register_operand" "")
7463                 (match_operand:DI 2 "nonimmediate_operand" "")))
7464    (set (match_operand:DI 3 "register_operand" "")
7465         (mod:DI (match_dup 1) (match_dup 2)))
7466    (clobber (reg:CC FLAGS_REG))]
7467   "TARGET_64BIT && reload_completed"
7468   [(parallel [(set (match_dup 3)
7469                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7470               (clobber (reg:CC FLAGS_REG))])
7471    (parallel [(set (match_dup 0)
7472                    (div:DI (reg:DI 0) (match_dup 2)))
7473               (set (match_dup 3)
7474                    (mod:DI (reg:DI 0) (match_dup 2)))
7475               (use (match_dup 3))
7476               (clobber (reg:CC FLAGS_REG))])]
7478   /* Avoid use of cltd in favor of a mov+shift.  */
7479   if (!TARGET_USE_CLTD && !optimize_size)
7480     {
7481       if (true_regnum (operands[1]))
7482         emit_move_insn (operands[0], operands[1]);
7483       else
7484         emit_move_insn (operands[3], operands[1]);
7485       operands[4] = operands[3];
7486     }
7487   else
7488     {
7489       gcc_assert (!true_regnum (operands[1]));
7490       operands[4] = operands[1];
7491     }
7495 (define_expand "divmodsi4"
7496   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7497                    (div:SI (match_operand:SI 1 "register_operand" "")
7498                            (match_operand:SI 2 "nonimmediate_operand" "")))
7499               (set (match_operand:SI 3 "register_operand" "")
7500                    (mod:SI (match_dup 1) (match_dup 2)))
7501               (clobber (reg:CC FLAGS_REG))])]
7502   ""
7503   "")
7505 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7506 ;; Penalize eax case slightly because it results in worse scheduling
7507 ;; of code.
7508 (define_insn "*divmodsi4_nocltd"
7509   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7510         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7511                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7512    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7513         (mod:SI (match_dup 2) (match_dup 3)))
7514    (clobber (reg:CC FLAGS_REG))]
7515   "!optimize_size && !TARGET_USE_CLTD"
7516   "#"
7517   [(set_attr "type" "multi")])
7519 (define_insn "*divmodsi4_cltd"
7520   [(set (match_operand:SI 0 "register_operand" "=a")
7521         (div:SI (match_operand:SI 2 "register_operand" "a")
7522                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7523    (set (match_operand:SI 1 "register_operand" "=&d")
7524         (mod:SI (match_dup 2) (match_dup 3)))
7525    (clobber (reg:CC FLAGS_REG))]
7526   "optimize_size || TARGET_USE_CLTD"
7527   "#"
7528   [(set_attr "type" "multi")])
7530 (define_insn "*divmodsi_noext"
7531   [(set (match_operand:SI 0 "register_operand" "=a")
7532         (div:SI (match_operand:SI 1 "register_operand" "0")
7533                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7534    (set (match_operand:SI 3 "register_operand" "=d")
7535         (mod:SI (match_dup 1) (match_dup 2)))
7536    (use (match_operand:SI 4 "register_operand" "3"))
7537    (clobber (reg:CC FLAGS_REG))]
7538   ""
7539   "idiv{l}\t%2"
7540   [(set_attr "type" "idiv")
7541    (set_attr "mode" "SI")])
7543 (define_split
7544   [(set (match_operand:SI 0 "register_operand" "")
7545         (div:SI (match_operand:SI 1 "register_operand" "")
7546                 (match_operand:SI 2 "nonimmediate_operand" "")))
7547    (set (match_operand:SI 3 "register_operand" "")
7548         (mod:SI (match_dup 1) (match_dup 2)))
7549    (clobber (reg:CC FLAGS_REG))]
7550   "reload_completed"
7551   [(parallel [(set (match_dup 3)
7552                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7553               (clobber (reg:CC FLAGS_REG))])
7554    (parallel [(set (match_dup 0)
7555                    (div:SI (reg:SI 0) (match_dup 2)))
7556               (set (match_dup 3)
7557                    (mod:SI (reg:SI 0) (match_dup 2)))
7558               (use (match_dup 3))
7559               (clobber (reg:CC FLAGS_REG))])]
7561   /* Avoid use of cltd in favor of a mov+shift.  */
7562   if (!TARGET_USE_CLTD && !optimize_size)
7563     {
7564       if (true_regnum (operands[1]))
7565         emit_move_insn (operands[0], operands[1]);
7566       else
7567         emit_move_insn (operands[3], operands[1]);
7568       operands[4] = operands[3];
7569     }
7570   else
7571     {
7572       gcc_assert (!true_regnum (operands[1]));
7573       operands[4] = operands[1];
7574     }
7576 ;; %%% Split me.
7577 (define_insn "divmodhi4"
7578   [(set (match_operand:HI 0 "register_operand" "=a")
7579         (div:HI (match_operand:HI 1 "register_operand" "0")
7580                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7581    (set (match_operand:HI 3 "register_operand" "=&d")
7582         (mod:HI (match_dup 1) (match_dup 2)))
7583    (clobber (reg:CC FLAGS_REG))]
7584   "TARGET_HIMODE_MATH"
7585   "cwtd\;idiv{w}\t%2"
7586   [(set_attr "type" "multi")
7587    (set_attr "length_immediate" "0")
7588    (set_attr "mode" "SI")])
7590 (define_insn "udivmoddi4"
7591   [(set (match_operand:DI 0 "register_operand" "=a")
7592         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7593                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7594    (set (match_operand:DI 3 "register_operand" "=&d")
7595         (umod:DI (match_dup 1) (match_dup 2)))
7596    (clobber (reg:CC FLAGS_REG))]
7597   "TARGET_64BIT"
7598   "xor{q}\t%3, %3\;div{q}\t%2"
7599   [(set_attr "type" "multi")
7600    (set_attr "length_immediate" "0")
7601    (set_attr "mode" "DI")])
7603 (define_insn "*udivmoddi4_noext"
7604   [(set (match_operand:DI 0 "register_operand" "=a")
7605         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7606                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7607    (set (match_operand:DI 3 "register_operand" "=d")
7608         (umod:DI (match_dup 1) (match_dup 2)))
7609    (use (match_dup 3))
7610    (clobber (reg:CC FLAGS_REG))]
7611   "TARGET_64BIT"
7612   "div{q}\t%2"
7613   [(set_attr "type" "idiv")
7614    (set_attr "mode" "DI")])
7616 (define_split
7617   [(set (match_operand:DI 0 "register_operand" "")
7618         (udiv:DI (match_operand:DI 1 "register_operand" "")
7619                  (match_operand:DI 2 "nonimmediate_operand" "")))
7620    (set (match_operand:DI 3 "register_operand" "")
7621         (umod:DI (match_dup 1) (match_dup 2)))
7622    (clobber (reg:CC FLAGS_REG))]
7623   "TARGET_64BIT && reload_completed"
7624   [(set (match_dup 3) (const_int 0))
7625    (parallel [(set (match_dup 0)
7626                    (udiv:DI (match_dup 1) (match_dup 2)))
7627               (set (match_dup 3)
7628                    (umod:DI (match_dup 1) (match_dup 2)))
7629               (use (match_dup 3))
7630               (clobber (reg:CC FLAGS_REG))])]
7631   "")
7633 (define_insn "udivmodsi4"
7634   [(set (match_operand:SI 0 "register_operand" "=a")
7635         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7636                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7637    (set (match_operand:SI 3 "register_operand" "=&d")
7638         (umod:SI (match_dup 1) (match_dup 2)))
7639    (clobber (reg:CC FLAGS_REG))]
7640   ""
7641   "xor{l}\t%3, %3\;div{l}\t%2"
7642   [(set_attr "type" "multi")
7643    (set_attr "length_immediate" "0")
7644    (set_attr "mode" "SI")])
7646 (define_insn "*udivmodsi4_noext"
7647   [(set (match_operand:SI 0 "register_operand" "=a")
7648         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7649                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7650    (set (match_operand:SI 3 "register_operand" "=d")
7651         (umod:SI (match_dup 1) (match_dup 2)))
7652    (use (match_dup 3))
7653    (clobber (reg:CC FLAGS_REG))]
7654   ""
7655   "div{l}\t%2"
7656   [(set_attr "type" "idiv")
7657    (set_attr "mode" "SI")])
7659 (define_split
7660   [(set (match_operand:SI 0 "register_operand" "")
7661         (udiv:SI (match_operand:SI 1 "register_operand" "")
7662                  (match_operand:SI 2 "nonimmediate_operand" "")))
7663    (set (match_operand:SI 3 "register_operand" "")
7664         (umod:SI (match_dup 1) (match_dup 2)))
7665    (clobber (reg:CC FLAGS_REG))]
7666   "reload_completed"
7667   [(set (match_dup 3) (const_int 0))
7668    (parallel [(set (match_dup 0)
7669                    (udiv:SI (match_dup 1) (match_dup 2)))
7670               (set (match_dup 3)
7671                    (umod:SI (match_dup 1) (match_dup 2)))
7672               (use (match_dup 3))
7673               (clobber (reg:CC FLAGS_REG))])]
7674   "")
7676 (define_expand "udivmodhi4"
7677   [(set (match_dup 4) (const_int 0))
7678    (parallel [(set (match_operand:HI 0 "register_operand" "")
7679                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7680                             (match_operand:HI 2 "nonimmediate_operand" "")))
7681               (set (match_operand:HI 3 "register_operand" "")
7682                    (umod:HI (match_dup 1) (match_dup 2)))
7683               (use (match_dup 4))
7684               (clobber (reg:CC FLAGS_REG))])]
7685   "TARGET_HIMODE_MATH"
7686   "operands[4] = gen_reg_rtx (HImode);")
7688 (define_insn "*udivmodhi_noext"
7689   [(set (match_operand:HI 0 "register_operand" "=a")
7690         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7691                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7692    (set (match_operand:HI 3 "register_operand" "=d")
7693         (umod:HI (match_dup 1) (match_dup 2)))
7694    (use (match_operand:HI 4 "register_operand" "3"))
7695    (clobber (reg:CC FLAGS_REG))]
7696   ""
7697   "div{w}\t%2"
7698   [(set_attr "type" "idiv")
7699    (set_attr "mode" "HI")])
7701 ;; We cannot use div/idiv for double division, because it causes
7702 ;; "division by zero" on the overflow and that's not what we expect
7703 ;; from truncate.  Because true (non truncating) double division is
7704 ;; never generated, we can't create this insn anyway.
7706 ;(define_insn ""
7707 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7708 ;       (truncate:SI
7709 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7710 ;                  (zero_extend:DI
7711 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7712 ;   (set (match_operand:SI 3 "register_operand" "=d")
7713 ;       (truncate:SI
7714 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7715 ;   (clobber (reg:CC FLAGS_REG))]
7716 ;  ""
7717 ;  "div{l}\t{%2, %0|%0, %2}"
7718 ;  [(set_attr "type" "idiv")])
7720 ;;- Logical AND instructions
7722 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7723 ;; Note that this excludes ah.
7725 (define_insn "*testdi_1_rex64"
7726   [(set (reg FLAGS_REG)
7727         (compare
7728           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7729                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7730           (const_int 0)))]
7731   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7732    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7733   "@
7734    test{l}\t{%k1, %k0|%k0, %k1}
7735    test{l}\t{%k1, %k0|%k0, %k1}
7736    test{q}\t{%1, %0|%0, %1}
7737    test{q}\t{%1, %0|%0, %1}
7738    test{q}\t{%1, %0|%0, %1}"
7739   [(set_attr "type" "test")
7740    (set_attr "modrm" "0,1,0,1,1")
7741    (set_attr "mode" "SI,SI,DI,DI,DI")
7742    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7744 (define_insn "testsi_1"
7745   [(set (reg FLAGS_REG)
7746         (compare
7747           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7748                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7749           (const_int 0)))]
7750   "ix86_match_ccmode (insn, CCNOmode)
7751    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7752   "test{l}\t{%1, %0|%0, %1}"
7753   [(set_attr "type" "test")
7754    (set_attr "modrm" "0,1,1")
7755    (set_attr "mode" "SI")
7756    (set_attr "pent_pair" "uv,np,uv")])
7758 (define_expand "testsi_ccno_1"
7759   [(set (reg:CCNO FLAGS_REG)
7760         (compare:CCNO
7761           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7762                   (match_operand:SI 1 "nonmemory_operand" ""))
7763           (const_int 0)))]
7764   ""
7765   "")
7767 (define_insn "*testhi_1"
7768   [(set (reg FLAGS_REG)
7769         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7770                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7771                  (const_int 0)))]
7772   "ix86_match_ccmode (insn, CCNOmode)
7773    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7774   "test{w}\t{%1, %0|%0, %1}"
7775   [(set_attr "type" "test")
7776    (set_attr "modrm" "0,1,1")
7777    (set_attr "mode" "HI")
7778    (set_attr "pent_pair" "uv,np,uv")])
7780 (define_expand "testqi_ccz_1"
7781   [(set (reg:CCZ FLAGS_REG)
7782         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7783                              (match_operand:QI 1 "nonmemory_operand" ""))
7784                  (const_int 0)))]
7785   ""
7786   "")
7788 (define_insn "*testqi_1_maybe_si"
7789   [(set (reg FLAGS_REG)
7790         (compare
7791           (and:QI
7792             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7793             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7794           (const_int 0)))]
7795    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7796     && ix86_match_ccmode (insn,
7797                          GET_CODE (operands[1]) == CONST_INT
7798                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7800   if (which_alternative == 3)
7801     {
7802       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7803         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7804       return "test{l}\t{%1, %k0|%k0, %1}";
7805     }
7806   return "test{b}\t{%1, %0|%0, %1}";
7808   [(set_attr "type" "test")
7809    (set_attr "modrm" "0,1,1,1")
7810    (set_attr "mode" "QI,QI,QI,SI")
7811    (set_attr "pent_pair" "uv,np,uv,np")])
7813 (define_insn "*testqi_1"
7814   [(set (reg FLAGS_REG)
7815         (compare
7816           (and:QI
7817             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7818             (match_operand:QI 1 "general_operand" "n,n,qn"))
7819           (const_int 0)))]
7820   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7821    && ix86_match_ccmode (insn, CCNOmode)"
7822   "test{b}\t{%1, %0|%0, %1}"
7823   [(set_attr "type" "test")
7824    (set_attr "modrm" "0,1,1")
7825    (set_attr "mode" "QI")
7826    (set_attr "pent_pair" "uv,np,uv")])
7828 (define_expand "testqi_ext_ccno_0"
7829   [(set (reg:CCNO FLAGS_REG)
7830         (compare:CCNO
7831           (and:SI
7832             (zero_extract:SI
7833               (match_operand 0 "ext_register_operand" "")
7834               (const_int 8)
7835               (const_int 8))
7836             (match_operand 1 "const_int_operand" ""))
7837           (const_int 0)))]
7838   ""
7839   "")
7841 (define_insn "*testqi_ext_0"
7842   [(set (reg FLAGS_REG)
7843         (compare
7844           (and:SI
7845             (zero_extract:SI
7846               (match_operand 0 "ext_register_operand" "Q")
7847               (const_int 8)
7848               (const_int 8))
7849             (match_operand 1 "const_int_operand" "n"))
7850           (const_int 0)))]
7851   "ix86_match_ccmode (insn, CCNOmode)"
7852   "test{b}\t{%1, %h0|%h0, %1}"
7853   [(set_attr "type" "test")
7854    (set_attr "mode" "QI")
7855    (set_attr "length_immediate" "1")
7856    (set_attr "pent_pair" "np")])
7858 (define_insn "*testqi_ext_1"
7859   [(set (reg FLAGS_REG)
7860         (compare
7861           (and:SI
7862             (zero_extract:SI
7863               (match_operand 0 "ext_register_operand" "Q")
7864               (const_int 8)
7865               (const_int 8))
7866             (zero_extend:SI
7867               (match_operand:QI 1 "general_operand" "Qm")))
7868           (const_int 0)))]
7869   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7870    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7871   "test{b}\t{%1, %h0|%h0, %1}"
7872   [(set_attr "type" "test")
7873    (set_attr "mode" "QI")])
7875 (define_insn "*testqi_ext_1_rex64"
7876   [(set (reg FLAGS_REG)
7877         (compare
7878           (and:SI
7879             (zero_extract:SI
7880               (match_operand 0 "ext_register_operand" "Q")
7881               (const_int 8)
7882               (const_int 8))
7883             (zero_extend:SI
7884               (match_operand:QI 1 "register_operand" "Q")))
7885           (const_int 0)))]
7886   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7887   "test{b}\t{%1, %h0|%h0, %1}"
7888   [(set_attr "type" "test")
7889    (set_attr "mode" "QI")])
7891 (define_insn "*testqi_ext_2"
7892   [(set (reg FLAGS_REG)
7893         (compare
7894           (and:SI
7895             (zero_extract:SI
7896               (match_operand 0 "ext_register_operand" "Q")
7897               (const_int 8)
7898               (const_int 8))
7899             (zero_extract:SI
7900               (match_operand 1 "ext_register_operand" "Q")
7901               (const_int 8)
7902               (const_int 8)))
7903           (const_int 0)))]
7904   "ix86_match_ccmode (insn, CCNOmode)"
7905   "test{b}\t{%h1, %h0|%h0, %h1}"
7906   [(set_attr "type" "test")
7907    (set_attr "mode" "QI")])
7909 ;; Combine likes to form bit extractions for some tests.  Humor it.
7910 (define_insn "*testqi_ext_3"
7911   [(set (reg FLAGS_REG)
7912         (compare (zero_extract:SI
7913                    (match_operand 0 "nonimmediate_operand" "rm")
7914                    (match_operand:SI 1 "const_int_operand" "")
7915                    (match_operand:SI 2 "const_int_operand" ""))
7916                  (const_int 0)))]
7917   "ix86_match_ccmode (insn, CCNOmode)
7918    && INTVAL (operands[1]) > 0
7919    && INTVAL (operands[2]) >= 0
7920    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7921    && (GET_MODE (operands[0]) == SImode
7922        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7923        || GET_MODE (operands[0]) == HImode
7924        || GET_MODE (operands[0]) == QImode)"
7925   "#")
7927 (define_insn "*testqi_ext_3_rex64"
7928   [(set (reg FLAGS_REG)
7929         (compare (zero_extract:DI
7930                    (match_operand 0 "nonimmediate_operand" "rm")
7931                    (match_operand:DI 1 "const_int_operand" "")
7932                    (match_operand:DI 2 "const_int_operand" ""))
7933                  (const_int 0)))]
7934   "TARGET_64BIT
7935    && ix86_match_ccmode (insn, CCNOmode)
7936    && INTVAL (operands[1]) > 0
7937    && INTVAL (operands[2]) >= 0
7938    /* Ensure that resulting mask is zero or sign extended operand.  */
7939    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7940        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7941            && INTVAL (operands[1]) > 32))
7942    && (GET_MODE (operands[0]) == SImode
7943        || GET_MODE (operands[0]) == DImode
7944        || GET_MODE (operands[0]) == HImode
7945        || GET_MODE (operands[0]) == QImode)"
7946   "#")
7948 (define_split
7949   [(set (match_operand 0 "flags_reg_operand" "")
7950         (match_operator 1 "compare_operator"
7951           [(zero_extract
7952              (match_operand 2 "nonimmediate_operand" "")
7953              (match_operand 3 "const_int_operand" "")
7954              (match_operand 4 "const_int_operand" ""))
7955            (const_int 0)]))]
7956   "ix86_match_ccmode (insn, CCNOmode)"
7957   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7959   rtx val = operands[2];
7960   HOST_WIDE_INT len = INTVAL (operands[3]);
7961   HOST_WIDE_INT pos = INTVAL (operands[4]);
7962   HOST_WIDE_INT mask;
7963   enum machine_mode mode, submode;
7965   mode = GET_MODE (val);
7966   if (GET_CODE (val) == MEM)
7967     {
7968       /* ??? Combine likes to put non-volatile mem extractions in QImode
7969          no matter the size of the test.  So find a mode that works.  */
7970       if (! MEM_VOLATILE_P (val))
7971         {
7972           mode = smallest_mode_for_size (pos + len, MODE_INT);
7973           val = adjust_address (val, mode, 0);
7974         }
7975     }
7976   else if (GET_CODE (val) == SUBREG
7977            && (submode = GET_MODE (SUBREG_REG (val)),
7978                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7979            && pos + len <= GET_MODE_BITSIZE (submode))
7980     {
7981       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7982       mode = submode;
7983       val = SUBREG_REG (val);
7984     }
7985   else if (mode == HImode && pos + len <= 8)
7986     {
7987       /* Small HImode tests can be converted to QImode.  */
7988       mode = QImode;
7989       val = gen_lowpart (QImode, val);
7990     }
7992   if (len == HOST_BITS_PER_WIDE_INT)
7993     mask = -1;
7994   else
7995     mask = ((HOST_WIDE_INT)1 << len) - 1;
7996   mask <<= pos;
7998   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8001 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8002 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8003 ;; this is relatively important trick.
8004 ;; Do the conversion only post-reload to avoid limiting of the register class
8005 ;; to QI regs.
8006 (define_split
8007   [(set (match_operand 0 "flags_reg_operand" "")
8008         (match_operator 1 "compare_operator"
8009           [(and (match_operand 2 "register_operand" "")
8010                 (match_operand 3 "const_int_operand" ""))
8011            (const_int 0)]))]
8012    "reload_completed
8013     && QI_REG_P (operands[2])
8014     && GET_MODE (operands[2]) != QImode
8015     && ((ix86_match_ccmode (insn, CCZmode)
8016          && !(INTVAL (operands[3]) & ~(255 << 8)))
8017         || (ix86_match_ccmode (insn, CCNOmode)
8018             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8019   [(set (match_dup 0)
8020         (match_op_dup 1
8021           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8022                    (match_dup 3))
8023            (const_int 0)]))]
8024   "operands[2] = gen_lowpart (SImode, operands[2]);
8025    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8027 (define_split
8028   [(set (match_operand 0 "flags_reg_operand" "")
8029         (match_operator 1 "compare_operator"
8030           [(and (match_operand 2 "nonimmediate_operand" "")
8031                 (match_operand 3 "const_int_operand" ""))
8032            (const_int 0)]))]
8033    "reload_completed
8034     && GET_MODE (operands[2]) != QImode
8035     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8036     && ((ix86_match_ccmode (insn, CCZmode)
8037          && !(INTVAL (operands[3]) & ~255))
8038         || (ix86_match_ccmode (insn, CCNOmode)
8039             && !(INTVAL (operands[3]) & ~127)))"
8040   [(set (match_dup 0)
8041         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8042                          (const_int 0)]))]
8043   "operands[2] = gen_lowpart (QImode, operands[2]);
8044    operands[3] = gen_lowpart (QImode, operands[3]);")
8047 ;; %%% This used to optimize known byte-wide and operations to memory,
8048 ;; and sometimes to QImode registers.  If this is considered useful,
8049 ;; it should be done with splitters.
8051 (define_expand "anddi3"
8052   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8053         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8054                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8055    (clobber (reg:CC FLAGS_REG))]
8056   "TARGET_64BIT"
8057   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8059 (define_insn "*anddi_1_rex64"
8060   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8061         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8062                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8063    (clobber (reg:CC FLAGS_REG))]
8064   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8066   switch (get_attr_type (insn))
8067     {
8068     case TYPE_IMOVX:
8069       {
8070         enum machine_mode mode;
8072         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8073         if (INTVAL (operands[2]) == 0xff)
8074           mode = QImode;
8075         else
8076           {
8077             gcc_assert (INTVAL (operands[2]) == 0xffff);
8078             mode = HImode;
8079           }
8080         
8081         operands[1] = gen_lowpart (mode, operands[1]);
8082         if (mode == QImode)
8083           return "movz{bq|x}\t{%1,%0|%0, %1}";
8084         else
8085           return "movz{wq|x}\t{%1,%0|%0, %1}";
8086       }
8088     default:
8089       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8090       if (get_attr_mode (insn) == MODE_SI)
8091         return "and{l}\t{%k2, %k0|%k0, %k2}";
8092       else
8093         return "and{q}\t{%2, %0|%0, %2}";
8094     }
8096   [(set_attr "type" "alu,alu,alu,imovx")
8097    (set_attr "length_immediate" "*,*,*,0")
8098    (set_attr "mode" "SI,DI,DI,DI")])
8100 (define_insn "*anddi_2"
8101   [(set (reg FLAGS_REG)
8102         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8103                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8104                  (const_int 0)))
8105    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8106         (and:DI (match_dup 1) (match_dup 2)))]
8107   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8108    && ix86_binary_operator_ok (AND, DImode, operands)"
8109   "@
8110    and{l}\t{%k2, %k0|%k0, %k2}
8111    and{q}\t{%2, %0|%0, %2}
8112    and{q}\t{%2, %0|%0, %2}"
8113   [(set_attr "type" "alu")
8114    (set_attr "mode" "SI,DI,DI")])
8116 (define_expand "andsi3"
8117   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8118         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8119                 (match_operand:SI 2 "general_operand" "")))
8120    (clobber (reg:CC FLAGS_REG))]
8121   ""
8122   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8124 (define_insn "*andsi_1"
8125   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8126         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8127                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8128    (clobber (reg:CC FLAGS_REG))]
8129   "ix86_binary_operator_ok (AND, SImode, operands)"
8131   switch (get_attr_type (insn))
8132     {
8133     case TYPE_IMOVX:
8134       {
8135         enum machine_mode mode;
8137         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8138         if (INTVAL (operands[2]) == 0xff)
8139           mode = QImode;
8140         else
8141           {
8142             gcc_assert (INTVAL (operands[2]) == 0xffff);
8143             mode = HImode;
8144           }
8145         
8146         operands[1] = gen_lowpart (mode, operands[1]);
8147         if (mode == QImode)
8148           return "movz{bl|x}\t{%1,%0|%0, %1}";
8149         else
8150           return "movz{wl|x}\t{%1,%0|%0, %1}";
8151       }
8153     default:
8154       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8155       return "and{l}\t{%2, %0|%0, %2}";
8156     }
8158   [(set_attr "type" "alu,alu,imovx")
8159    (set_attr "length_immediate" "*,*,0")
8160    (set_attr "mode" "SI")])
8162 (define_split
8163   [(set (match_operand 0 "register_operand" "")
8164         (and (match_dup 0)
8165              (const_int -65536)))
8166    (clobber (reg:CC FLAGS_REG))]
8167   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8168   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8169   "operands[1] = gen_lowpart (HImode, operands[0]);")
8171 (define_split
8172   [(set (match_operand 0 "ext_register_operand" "")
8173         (and (match_dup 0)
8174              (const_int -256)))
8175    (clobber (reg:CC FLAGS_REG))]
8176   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8177   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8178   "operands[1] = gen_lowpart (QImode, operands[0]);")
8180 (define_split
8181   [(set (match_operand 0 "ext_register_operand" "")
8182         (and (match_dup 0)
8183              (const_int -65281)))
8184    (clobber (reg:CC FLAGS_REG))]
8185   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8186   [(parallel [(set (zero_extract:SI (match_dup 0)
8187                                     (const_int 8)
8188                                     (const_int 8))
8189                    (xor:SI 
8190                      (zero_extract:SI (match_dup 0)
8191                                       (const_int 8)
8192                                       (const_int 8))
8193                      (zero_extract:SI (match_dup 0)
8194                                       (const_int 8)
8195                                       (const_int 8))))
8196               (clobber (reg:CC FLAGS_REG))])]
8197   "operands[0] = gen_lowpart (SImode, operands[0]);")
8199 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8200 (define_insn "*andsi_1_zext"
8201   [(set (match_operand:DI 0 "register_operand" "=r")
8202         (zero_extend:DI
8203           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8204                   (match_operand:SI 2 "general_operand" "rim"))))
8205    (clobber (reg:CC FLAGS_REG))]
8206   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8207   "and{l}\t{%2, %k0|%k0, %2}"
8208   [(set_attr "type" "alu")
8209    (set_attr "mode" "SI")])
8211 (define_insn "*andsi_2"
8212   [(set (reg FLAGS_REG)
8213         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8214                          (match_operand:SI 2 "general_operand" "rim,ri"))
8215                  (const_int 0)))
8216    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8217         (and:SI (match_dup 1) (match_dup 2)))]
8218   "ix86_match_ccmode (insn, CCNOmode)
8219    && ix86_binary_operator_ok (AND, SImode, operands)"
8220   "and{l}\t{%2, %0|%0, %2}"
8221   [(set_attr "type" "alu")
8222    (set_attr "mode" "SI")])
8224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8225 (define_insn "*andsi_2_zext"
8226   [(set (reg FLAGS_REG)
8227         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8228                          (match_operand:SI 2 "general_operand" "rim"))
8229                  (const_int 0)))
8230    (set (match_operand:DI 0 "register_operand" "=r")
8231         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8232   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8233    && ix86_binary_operator_ok (AND, SImode, operands)"
8234   "and{l}\t{%2, %k0|%k0, %2}"
8235   [(set_attr "type" "alu")
8236    (set_attr "mode" "SI")])
8238 (define_expand "andhi3"
8239   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8240         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8241                 (match_operand:HI 2 "general_operand" "")))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "TARGET_HIMODE_MATH"
8244   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8246 (define_insn "*andhi_1"
8247   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8248         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8249                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8250    (clobber (reg:CC FLAGS_REG))]
8251   "ix86_binary_operator_ok (AND, HImode, operands)"
8253   switch (get_attr_type (insn))
8254     {
8255     case TYPE_IMOVX:
8256       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8257       gcc_assert (INTVAL (operands[2]) == 0xff);
8258       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8260     default:
8261       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8263       return "and{w}\t{%2, %0|%0, %2}";
8264     }
8266   [(set_attr "type" "alu,alu,imovx")
8267    (set_attr "length_immediate" "*,*,0")
8268    (set_attr "mode" "HI,HI,SI")])
8270 (define_insn "*andhi_2"
8271   [(set (reg FLAGS_REG)
8272         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8273                          (match_operand:HI 2 "general_operand" "rim,ri"))
8274                  (const_int 0)))
8275    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8276         (and:HI (match_dup 1) (match_dup 2)))]
8277   "ix86_match_ccmode (insn, CCNOmode)
8278    && ix86_binary_operator_ok (AND, HImode, operands)"
8279   "and{w}\t{%2, %0|%0, %2}"
8280   [(set_attr "type" "alu")
8281    (set_attr "mode" "HI")])
8283 (define_expand "andqi3"
8284   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8285         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8286                 (match_operand:QI 2 "general_operand" "")))
8287    (clobber (reg:CC FLAGS_REG))]
8288   "TARGET_QIMODE_MATH"
8289   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8291 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8292 (define_insn "*andqi_1"
8293   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8294         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8295                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8296    (clobber (reg:CC FLAGS_REG))]
8297   "ix86_binary_operator_ok (AND, QImode, operands)"
8298   "@
8299    and{b}\t{%2, %0|%0, %2}
8300    and{b}\t{%2, %0|%0, %2}
8301    and{l}\t{%k2, %k0|%k0, %k2}"
8302   [(set_attr "type" "alu")
8303    (set_attr "mode" "QI,QI,SI")])
8305 (define_insn "*andqi_1_slp"
8306   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8307         (and:QI (match_dup 0)
8308                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8309    (clobber (reg:CC FLAGS_REG))]
8310   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8311    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8312   "and{b}\t{%1, %0|%0, %1}"
8313   [(set_attr "type" "alu1")
8314    (set_attr "mode" "QI")])
8316 (define_insn "*andqi_2_maybe_si"
8317   [(set (reg FLAGS_REG)
8318         (compare (and:QI
8319                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8320                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8321                  (const_int 0)))
8322    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8323         (and:QI (match_dup 1) (match_dup 2)))]
8324   "ix86_binary_operator_ok (AND, QImode, operands)
8325    && ix86_match_ccmode (insn,
8326                          GET_CODE (operands[2]) == CONST_INT
8327                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8329   if (which_alternative == 2)
8330     {
8331       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8332         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8333       return "and{l}\t{%2, %k0|%k0, %2}";
8334     }
8335   return "and{b}\t{%2, %0|%0, %2}";
8337   [(set_attr "type" "alu")
8338    (set_attr "mode" "QI,QI,SI")])
8340 (define_insn "*andqi_2"
8341   [(set (reg FLAGS_REG)
8342         (compare (and:QI
8343                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8344                    (match_operand:QI 2 "general_operand" "qim,qi"))
8345                  (const_int 0)))
8346    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8347         (and:QI (match_dup 1) (match_dup 2)))]
8348   "ix86_match_ccmode (insn, CCNOmode)
8349    && ix86_binary_operator_ok (AND, QImode, operands)"
8350   "and{b}\t{%2, %0|%0, %2}"
8351   [(set_attr "type" "alu")
8352    (set_attr "mode" "QI")])
8354 (define_insn "*andqi_2_slp"
8355   [(set (reg FLAGS_REG)
8356         (compare (and:QI
8357                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8358                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8359                  (const_int 0)))
8360    (set (strict_low_part (match_dup 0))
8361         (and:QI (match_dup 0) (match_dup 1)))]
8362   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8363    && ix86_match_ccmode (insn, CCNOmode)
8364    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8365   "and{b}\t{%1, %0|%0, %1}"
8366   [(set_attr "type" "alu1")
8367    (set_attr "mode" "QI")])
8369 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8370 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8371 ;; for a QImode operand, which of course failed.
8373 (define_insn "andqi_ext_0"
8374   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8375                          (const_int 8)
8376                          (const_int 8))
8377         (and:SI 
8378           (zero_extract:SI
8379             (match_operand 1 "ext_register_operand" "0")
8380             (const_int 8)
8381             (const_int 8))
8382           (match_operand 2 "const_int_operand" "n")))
8383    (clobber (reg:CC FLAGS_REG))]
8384   ""
8385   "and{b}\t{%2, %h0|%h0, %2}"
8386   [(set_attr "type" "alu")
8387    (set_attr "length_immediate" "1")
8388    (set_attr "mode" "QI")])
8390 ;; Generated by peephole translating test to and.  This shows up
8391 ;; often in fp comparisons.
8393 (define_insn "*andqi_ext_0_cc"
8394   [(set (reg FLAGS_REG)
8395         (compare
8396           (and:SI
8397             (zero_extract:SI
8398               (match_operand 1 "ext_register_operand" "0")
8399               (const_int 8)
8400               (const_int 8))
8401             (match_operand 2 "const_int_operand" "n"))
8402           (const_int 0)))
8403    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8404                          (const_int 8)
8405                          (const_int 8))
8406         (and:SI 
8407           (zero_extract:SI
8408             (match_dup 1)
8409             (const_int 8)
8410             (const_int 8))
8411           (match_dup 2)))]
8412   "ix86_match_ccmode (insn, CCNOmode)"
8413   "and{b}\t{%2, %h0|%h0, %2}"
8414   [(set_attr "type" "alu")
8415    (set_attr "length_immediate" "1")
8416    (set_attr "mode" "QI")])
8418 (define_insn "*andqi_ext_1"
8419   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8420                          (const_int 8)
8421                          (const_int 8))
8422         (and:SI 
8423           (zero_extract:SI
8424             (match_operand 1 "ext_register_operand" "0")
8425             (const_int 8)
8426             (const_int 8))
8427           (zero_extend:SI
8428             (match_operand:QI 2 "general_operand" "Qm"))))
8429    (clobber (reg:CC FLAGS_REG))]
8430   "!TARGET_64BIT"
8431   "and{b}\t{%2, %h0|%h0, %2}"
8432   [(set_attr "type" "alu")
8433    (set_attr "length_immediate" "0")
8434    (set_attr "mode" "QI")])
8436 (define_insn "*andqi_ext_1_rex64"
8437   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8438                          (const_int 8)
8439                          (const_int 8))
8440         (and:SI 
8441           (zero_extract:SI
8442             (match_operand 1 "ext_register_operand" "0")
8443             (const_int 8)
8444             (const_int 8))
8445           (zero_extend:SI
8446             (match_operand 2 "ext_register_operand" "Q"))))
8447    (clobber (reg:CC FLAGS_REG))]
8448   "TARGET_64BIT"
8449   "and{b}\t{%2, %h0|%h0, %2}"
8450   [(set_attr "type" "alu")
8451    (set_attr "length_immediate" "0")
8452    (set_attr "mode" "QI")])
8454 (define_insn "*andqi_ext_2"
8455   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8456                          (const_int 8)
8457                          (const_int 8))
8458         (and:SI
8459           (zero_extract:SI
8460             (match_operand 1 "ext_register_operand" "%0")
8461             (const_int 8)
8462             (const_int 8))
8463           (zero_extract:SI
8464             (match_operand 2 "ext_register_operand" "Q")
8465             (const_int 8)
8466             (const_int 8))))
8467    (clobber (reg:CC FLAGS_REG))]
8468   ""
8469   "and{b}\t{%h2, %h0|%h0, %h2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "length_immediate" "0")
8472    (set_attr "mode" "QI")])
8474 ;; Convert wide AND instructions with immediate operand to shorter QImode
8475 ;; equivalents when possible.
8476 ;; Don't do the splitting with memory operands, since it introduces risk
8477 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8478 ;; for size, but that can (should?) be handled by generic code instead.
8479 (define_split
8480   [(set (match_operand 0 "register_operand" "")
8481         (and (match_operand 1 "register_operand" "")
8482              (match_operand 2 "const_int_operand" "")))
8483    (clobber (reg:CC FLAGS_REG))]
8484    "reload_completed
8485     && QI_REG_P (operands[0])
8486     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8487     && !(~INTVAL (operands[2]) & ~(255 << 8))
8488     && GET_MODE (operands[0]) != QImode"
8489   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8490                    (and:SI (zero_extract:SI (match_dup 1)
8491                                             (const_int 8) (const_int 8))
8492                            (match_dup 2)))
8493               (clobber (reg:CC FLAGS_REG))])]
8494   "operands[0] = gen_lowpart (SImode, operands[0]);
8495    operands[1] = gen_lowpart (SImode, operands[1]);
8496    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8498 ;; Since AND can be encoded with sign extended immediate, this is only
8499 ;; profitable when 7th bit is not set.
8500 (define_split
8501   [(set (match_operand 0 "register_operand" "")
8502         (and (match_operand 1 "general_operand" "")
8503              (match_operand 2 "const_int_operand" "")))
8504    (clobber (reg:CC FLAGS_REG))]
8505    "reload_completed
8506     && ANY_QI_REG_P (operands[0])
8507     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8508     && !(~INTVAL (operands[2]) & ~255)
8509     && !(INTVAL (operands[2]) & 128)
8510     && GET_MODE (operands[0]) != QImode"
8511   [(parallel [(set (strict_low_part (match_dup 0))
8512                    (and:QI (match_dup 1)
8513                            (match_dup 2)))
8514               (clobber (reg:CC FLAGS_REG))])]
8515   "operands[0] = gen_lowpart (QImode, operands[0]);
8516    operands[1] = gen_lowpart (QImode, operands[1]);
8517    operands[2] = gen_lowpart (QImode, operands[2]);")
8519 ;; Logical inclusive OR instructions
8521 ;; %%% This used to optimize known byte-wide and operations to memory.
8522 ;; If this is considered useful, it should be done with splitters.
8524 (define_expand "iordi3"
8525   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8526         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8527                 (match_operand:DI 2 "x86_64_general_operand" "")))
8528    (clobber (reg:CC FLAGS_REG))]
8529   "TARGET_64BIT"
8530   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8532 (define_insn "*iordi_1_rex64"
8533   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8534         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8535                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8536    (clobber (reg:CC FLAGS_REG))]
8537   "TARGET_64BIT
8538    && ix86_binary_operator_ok (IOR, DImode, operands)"
8539   "or{q}\t{%2, %0|%0, %2}"
8540   [(set_attr "type" "alu")
8541    (set_attr "mode" "DI")])
8543 (define_insn "*iordi_2_rex64"
8544   [(set (reg FLAGS_REG)
8545         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8546                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8547                  (const_int 0)))
8548    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8549         (ior:DI (match_dup 1) (match_dup 2)))]
8550   "TARGET_64BIT
8551    && ix86_match_ccmode (insn, CCNOmode)
8552    && ix86_binary_operator_ok (IOR, DImode, operands)"
8553   "or{q}\t{%2, %0|%0, %2}"
8554   [(set_attr "type" "alu")
8555    (set_attr "mode" "DI")])
8557 (define_insn "*iordi_3_rex64"
8558   [(set (reg FLAGS_REG)
8559         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8560                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8561                  (const_int 0)))
8562    (clobber (match_scratch:DI 0 "=r"))]
8563   "TARGET_64BIT
8564    && ix86_match_ccmode (insn, CCNOmode)
8565    && ix86_binary_operator_ok (IOR, DImode, operands)"
8566   "or{q}\t{%2, %0|%0, %2}"
8567   [(set_attr "type" "alu")
8568    (set_attr "mode" "DI")])
8571 (define_expand "iorsi3"
8572   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8573         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8574                 (match_operand:SI 2 "general_operand" "")))
8575    (clobber (reg:CC FLAGS_REG))]
8576   ""
8577   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8579 (define_insn "*iorsi_1"
8580   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8581         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8582                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8583    (clobber (reg:CC FLAGS_REG))]
8584   "ix86_binary_operator_ok (IOR, SImode, operands)"
8585   "or{l}\t{%2, %0|%0, %2}"
8586   [(set_attr "type" "alu")
8587    (set_attr "mode" "SI")])
8589 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8590 (define_insn "*iorsi_1_zext"
8591   [(set (match_operand:DI 0 "register_operand" "=rm")
8592         (zero_extend:DI
8593           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8594                   (match_operand:SI 2 "general_operand" "rim"))))
8595    (clobber (reg:CC FLAGS_REG))]
8596   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8597   "or{l}\t{%2, %k0|%k0, %2}"
8598   [(set_attr "type" "alu")
8599    (set_attr "mode" "SI")])
8601 (define_insn "*iorsi_1_zext_imm"
8602   [(set (match_operand:DI 0 "register_operand" "=rm")
8603         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8604                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8605    (clobber (reg:CC FLAGS_REG))]
8606   "TARGET_64BIT"
8607   "or{l}\t{%2, %k0|%k0, %2}"
8608   [(set_attr "type" "alu")
8609    (set_attr "mode" "SI")])
8611 (define_insn "*iorsi_2"
8612   [(set (reg FLAGS_REG)
8613         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8614                          (match_operand:SI 2 "general_operand" "rim,ri"))
8615                  (const_int 0)))
8616    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8617         (ior:SI (match_dup 1) (match_dup 2)))]
8618   "ix86_match_ccmode (insn, CCNOmode)
8619    && ix86_binary_operator_ok (IOR, SImode, operands)"
8620   "or{l}\t{%2, %0|%0, %2}"
8621   [(set_attr "type" "alu")
8622    (set_attr "mode" "SI")])
8624 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8625 ;; ??? Special case for immediate operand is missing - it is tricky.
8626 (define_insn "*iorsi_2_zext"
8627   [(set (reg FLAGS_REG)
8628         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8629                          (match_operand:SI 2 "general_operand" "rim"))
8630                  (const_int 0)))
8631    (set (match_operand:DI 0 "register_operand" "=r")
8632         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8633   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8634    && ix86_binary_operator_ok (IOR, SImode, operands)"
8635   "or{l}\t{%2, %k0|%k0, %2}"
8636   [(set_attr "type" "alu")
8637    (set_attr "mode" "SI")])
8639 (define_insn "*iorsi_2_zext_imm"
8640   [(set (reg FLAGS_REG)
8641         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8642                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8643                  (const_int 0)))
8644    (set (match_operand:DI 0 "register_operand" "=r")
8645         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8646   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8647    && ix86_binary_operator_ok (IOR, SImode, operands)"
8648   "or{l}\t{%2, %k0|%k0, %2}"
8649   [(set_attr "type" "alu")
8650    (set_attr "mode" "SI")])
8652 (define_insn "*iorsi_3"
8653   [(set (reg FLAGS_REG)
8654         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8655                          (match_operand:SI 2 "general_operand" "rim"))
8656                  (const_int 0)))
8657    (clobber (match_scratch:SI 0 "=r"))]
8658   "ix86_match_ccmode (insn, CCNOmode)
8659    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8660   "or{l}\t{%2, %0|%0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "mode" "SI")])
8664 (define_expand "iorhi3"
8665   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8666         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8667                 (match_operand:HI 2 "general_operand" "")))
8668    (clobber (reg:CC FLAGS_REG))]
8669   "TARGET_HIMODE_MATH"
8670   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8672 (define_insn "*iorhi_1"
8673   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8674         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8675                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8676    (clobber (reg:CC FLAGS_REG))]
8677   "ix86_binary_operator_ok (IOR, HImode, operands)"
8678   "or{w}\t{%2, %0|%0, %2}"
8679   [(set_attr "type" "alu")
8680    (set_attr "mode" "HI")])
8682 (define_insn "*iorhi_2"
8683   [(set (reg FLAGS_REG)
8684         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8685                          (match_operand:HI 2 "general_operand" "rim,ri"))
8686                  (const_int 0)))
8687    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8688         (ior:HI (match_dup 1) (match_dup 2)))]
8689   "ix86_match_ccmode (insn, CCNOmode)
8690    && ix86_binary_operator_ok (IOR, HImode, operands)"
8691   "or{w}\t{%2, %0|%0, %2}"
8692   [(set_attr "type" "alu")
8693    (set_attr "mode" "HI")])
8695 (define_insn "*iorhi_3"
8696   [(set (reg FLAGS_REG)
8697         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8698                          (match_operand:HI 2 "general_operand" "rim"))
8699                  (const_int 0)))
8700    (clobber (match_scratch:HI 0 "=r"))]
8701   "ix86_match_ccmode (insn, CCNOmode)
8702    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8703   "or{w}\t{%2, %0|%0, %2}"
8704   [(set_attr "type" "alu")
8705    (set_attr "mode" "HI")])
8707 (define_expand "iorqi3"
8708   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8709         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8710                 (match_operand:QI 2 "general_operand" "")))
8711    (clobber (reg:CC FLAGS_REG))]
8712   "TARGET_QIMODE_MATH"
8713   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8715 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8716 (define_insn "*iorqi_1"
8717   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8718         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8719                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8720    (clobber (reg:CC FLAGS_REG))]
8721   "ix86_binary_operator_ok (IOR, QImode, operands)"
8722   "@
8723    or{b}\t{%2, %0|%0, %2}
8724    or{b}\t{%2, %0|%0, %2}
8725    or{l}\t{%k2, %k0|%k0, %k2}"
8726   [(set_attr "type" "alu")
8727    (set_attr "mode" "QI,QI,SI")])
8729 (define_insn "*iorqi_1_slp"
8730   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8731         (ior:QI (match_dup 0)
8732                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8733    (clobber (reg:CC FLAGS_REG))]
8734   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8735    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8736   "or{b}\t{%1, %0|%0, %1}"
8737   [(set_attr "type" "alu1")
8738    (set_attr "mode" "QI")])
8740 (define_insn "*iorqi_2"
8741   [(set (reg FLAGS_REG)
8742         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8743                          (match_operand:QI 2 "general_operand" "qim,qi"))
8744                  (const_int 0)))
8745    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8746         (ior:QI (match_dup 1) (match_dup 2)))]
8747   "ix86_match_ccmode (insn, CCNOmode)
8748    && ix86_binary_operator_ok (IOR, QImode, operands)"
8749   "or{b}\t{%2, %0|%0, %2}"
8750   [(set_attr "type" "alu")
8751    (set_attr "mode" "QI")])
8753 (define_insn "*iorqi_2_slp"
8754   [(set (reg FLAGS_REG)
8755         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8756                          (match_operand:QI 1 "general_operand" "qim,qi"))
8757                  (const_int 0)))
8758    (set (strict_low_part (match_dup 0))
8759         (ior:QI (match_dup 0) (match_dup 1)))]
8760   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8761    && ix86_match_ccmode (insn, CCNOmode)
8762    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8763   "or{b}\t{%1, %0|%0, %1}"
8764   [(set_attr "type" "alu1")
8765    (set_attr "mode" "QI")])
8767 (define_insn "*iorqi_3"
8768   [(set (reg FLAGS_REG)
8769         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8770                          (match_operand:QI 2 "general_operand" "qim"))
8771                  (const_int 0)))
8772    (clobber (match_scratch:QI 0 "=q"))]
8773   "ix86_match_ccmode (insn, CCNOmode)
8774    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8775   "or{b}\t{%2, %0|%0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "mode" "QI")])
8779 (define_insn "iorqi_ext_0"
8780   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8781                          (const_int 8)
8782                          (const_int 8))
8783         (ior:SI 
8784           (zero_extract:SI
8785             (match_operand 1 "ext_register_operand" "0")
8786             (const_int 8)
8787             (const_int 8))
8788           (match_operand 2 "const_int_operand" "n")))
8789    (clobber (reg:CC FLAGS_REG))]
8790   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8791   "or{b}\t{%2, %h0|%h0, %2}"
8792   [(set_attr "type" "alu")
8793    (set_attr "length_immediate" "1")
8794    (set_attr "mode" "QI")])
8796 (define_insn "*iorqi_ext_1"
8797   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8798                          (const_int 8)
8799                          (const_int 8))
8800         (ior:SI 
8801           (zero_extract:SI
8802             (match_operand 1 "ext_register_operand" "0")
8803             (const_int 8)
8804             (const_int 8))
8805           (zero_extend:SI
8806             (match_operand:QI 2 "general_operand" "Qm"))))
8807    (clobber (reg:CC FLAGS_REG))]
8808   "!TARGET_64BIT
8809    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8810   "or{b}\t{%2, %h0|%h0, %2}"
8811   [(set_attr "type" "alu")
8812    (set_attr "length_immediate" "0")
8813    (set_attr "mode" "QI")])
8815 (define_insn "*iorqi_ext_1_rex64"
8816   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8817                          (const_int 8)
8818                          (const_int 8))
8819         (ior:SI 
8820           (zero_extract:SI
8821             (match_operand 1 "ext_register_operand" "0")
8822             (const_int 8)
8823             (const_int 8))
8824           (zero_extend:SI
8825             (match_operand 2 "ext_register_operand" "Q"))))
8826    (clobber (reg:CC FLAGS_REG))]
8827   "TARGET_64BIT
8828    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8829   "or{b}\t{%2, %h0|%h0, %2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "length_immediate" "0")
8832    (set_attr "mode" "QI")])
8834 (define_insn "*iorqi_ext_2"
8835   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8836                          (const_int 8)
8837                          (const_int 8))
8838         (ior:SI 
8839           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8840                            (const_int 8)
8841                            (const_int 8))
8842           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8843                            (const_int 8)
8844                            (const_int 8))))
8845    (clobber (reg:CC FLAGS_REG))]
8846   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8847   "ior{b}\t{%h2, %h0|%h0, %h2}"
8848   [(set_attr "type" "alu")
8849    (set_attr "length_immediate" "0")
8850    (set_attr "mode" "QI")])
8852 (define_split
8853   [(set (match_operand 0 "register_operand" "")
8854         (ior (match_operand 1 "register_operand" "")
8855              (match_operand 2 "const_int_operand" "")))
8856    (clobber (reg:CC FLAGS_REG))]
8857    "reload_completed
8858     && QI_REG_P (operands[0])
8859     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8860     && !(INTVAL (operands[2]) & ~(255 << 8))
8861     && GET_MODE (operands[0]) != QImode"
8862   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8863                    (ior:SI (zero_extract:SI (match_dup 1)
8864                                             (const_int 8) (const_int 8))
8865                            (match_dup 2)))
8866               (clobber (reg:CC FLAGS_REG))])]
8867   "operands[0] = gen_lowpart (SImode, operands[0]);
8868    operands[1] = gen_lowpart (SImode, operands[1]);
8869    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8871 ;; Since OR can be encoded with sign extended immediate, this is only
8872 ;; profitable when 7th bit is set.
8873 (define_split
8874   [(set (match_operand 0 "register_operand" "")
8875         (ior (match_operand 1 "general_operand" "")
8876              (match_operand 2 "const_int_operand" "")))
8877    (clobber (reg:CC FLAGS_REG))]
8878    "reload_completed
8879     && ANY_QI_REG_P (operands[0])
8880     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8881     && !(INTVAL (operands[2]) & ~255)
8882     && (INTVAL (operands[2]) & 128)
8883     && GET_MODE (operands[0]) != QImode"
8884   [(parallel [(set (strict_low_part (match_dup 0))
8885                    (ior:QI (match_dup 1)
8886                            (match_dup 2)))
8887               (clobber (reg:CC FLAGS_REG))])]
8888   "operands[0] = gen_lowpart (QImode, operands[0]);
8889    operands[1] = gen_lowpart (QImode, operands[1]);
8890    operands[2] = gen_lowpart (QImode, operands[2]);")
8892 ;; Logical XOR instructions
8894 ;; %%% This used to optimize known byte-wide and operations to memory.
8895 ;; If this is considered useful, it should be done with splitters.
8897 (define_expand "xordi3"
8898   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8899         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8900                 (match_operand:DI 2 "x86_64_general_operand" "")))
8901    (clobber (reg:CC FLAGS_REG))]
8902   "TARGET_64BIT"
8903   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8905 (define_insn "*xordi_1_rex64"
8906   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8907         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8908                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8909    (clobber (reg:CC FLAGS_REG))]
8910   "TARGET_64BIT
8911    && ix86_binary_operator_ok (XOR, DImode, operands)"
8912   "@
8913    xor{q}\t{%2, %0|%0, %2}
8914    xor{q}\t{%2, %0|%0, %2}"
8915   [(set_attr "type" "alu")
8916    (set_attr "mode" "DI,DI")])
8918 (define_insn "*xordi_2_rex64"
8919   [(set (reg FLAGS_REG)
8920         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8921                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8922                  (const_int 0)))
8923    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8924         (xor:DI (match_dup 1) (match_dup 2)))]
8925   "TARGET_64BIT
8926    && ix86_match_ccmode (insn, CCNOmode)
8927    && ix86_binary_operator_ok (XOR, DImode, operands)"
8928   "@
8929    xor{q}\t{%2, %0|%0, %2}
8930    xor{q}\t{%2, %0|%0, %2}"
8931   [(set_attr "type" "alu")
8932    (set_attr "mode" "DI,DI")])
8934 (define_insn "*xordi_3_rex64"
8935   [(set (reg FLAGS_REG)
8936         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8937                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8938                  (const_int 0)))
8939    (clobber (match_scratch:DI 0 "=r"))]
8940   "TARGET_64BIT
8941    && ix86_match_ccmode (insn, CCNOmode)
8942    && ix86_binary_operator_ok (XOR, DImode, operands)"
8943   "xor{q}\t{%2, %0|%0, %2}"
8944   [(set_attr "type" "alu")
8945    (set_attr "mode" "DI")])
8947 (define_expand "xorsi3"
8948   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8949         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8950                 (match_operand:SI 2 "general_operand" "")))
8951    (clobber (reg:CC FLAGS_REG))]
8952   ""
8953   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8955 (define_insn "*xorsi_1"
8956   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8957         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8958                 (match_operand:SI 2 "general_operand" "ri,rm")))
8959    (clobber (reg:CC FLAGS_REG))]
8960   "ix86_binary_operator_ok (XOR, SImode, operands)"
8961   "xor{l}\t{%2, %0|%0, %2}"
8962   [(set_attr "type" "alu")
8963    (set_attr "mode" "SI")])
8965 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8966 ;; Add speccase for immediates
8967 (define_insn "*xorsi_1_zext"
8968   [(set (match_operand:DI 0 "register_operand" "=r")
8969         (zero_extend:DI
8970           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8971                   (match_operand:SI 2 "general_operand" "rim"))))
8972    (clobber (reg:CC FLAGS_REG))]
8973   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8974   "xor{l}\t{%2, %k0|%k0, %2}"
8975   [(set_attr "type" "alu")
8976    (set_attr "mode" "SI")])
8978 (define_insn "*xorsi_1_zext_imm"
8979   [(set (match_operand:DI 0 "register_operand" "=r")
8980         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8981                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8982    (clobber (reg:CC FLAGS_REG))]
8983   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8984   "xor{l}\t{%2, %k0|%k0, %2}"
8985   [(set_attr "type" "alu")
8986    (set_attr "mode" "SI")])
8988 (define_insn "*xorsi_2"
8989   [(set (reg FLAGS_REG)
8990         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8991                          (match_operand:SI 2 "general_operand" "rim,ri"))
8992                  (const_int 0)))
8993    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8994         (xor:SI (match_dup 1) (match_dup 2)))]
8995   "ix86_match_ccmode (insn, CCNOmode)
8996    && ix86_binary_operator_ok (XOR, SImode, operands)"
8997   "xor{l}\t{%2, %0|%0, %2}"
8998   [(set_attr "type" "alu")
8999    (set_attr "mode" "SI")])
9001 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9002 ;; ??? Special case for immediate operand is missing - it is tricky.
9003 (define_insn "*xorsi_2_zext"
9004   [(set (reg FLAGS_REG)
9005         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9006                          (match_operand:SI 2 "general_operand" "rim"))
9007                  (const_int 0)))
9008    (set (match_operand:DI 0 "register_operand" "=r")
9009         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9010   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9011    && ix86_binary_operator_ok (XOR, SImode, operands)"
9012   "xor{l}\t{%2, %k0|%k0, %2}"
9013   [(set_attr "type" "alu")
9014    (set_attr "mode" "SI")])
9016 (define_insn "*xorsi_2_zext_imm"
9017   [(set (reg FLAGS_REG)
9018         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9019                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9020                  (const_int 0)))
9021    (set (match_operand:DI 0 "register_operand" "=r")
9022         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9023   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9024    && ix86_binary_operator_ok (XOR, SImode, operands)"
9025   "xor{l}\t{%2, %k0|%k0, %2}"
9026   [(set_attr "type" "alu")
9027    (set_attr "mode" "SI")])
9029 (define_insn "*xorsi_3"
9030   [(set (reg FLAGS_REG)
9031         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9032                          (match_operand:SI 2 "general_operand" "rim"))
9033                  (const_int 0)))
9034    (clobber (match_scratch:SI 0 "=r"))]
9035   "ix86_match_ccmode (insn, CCNOmode)
9036    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9037   "xor{l}\t{%2, %0|%0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "mode" "SI")])
9041 (define_expand "xorhi3"
9042   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9043         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9044                 (match_operand:HI 2 "general_operand" "")))
9045    (clobber (reg:CC FLAGS_REG))]
9046   "TARGET_HIMODE_MATH"
9047   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9049 (define_insn "*xorhi_1"
9050   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9051         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9052                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9053    (clobber (reg:CC FLAGS_REG))]
9054   "ix86_binary_operator_ok (XOR, HImode, operands)"
9055   "xor{w}\t{%2, %0|%0, %2}"
9056   [(set_attr "type" "alu")
9057    (set_attr "mode" "HI")])
9059 (define_insn "*xorhi_2"
9060   [(set (reg FLAGS_REG)
9061         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9062                          (match_operand:HI 2 "general_operand" "rim,ri"))
9063                  (const_int 0)))
9064    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9065         (xor:HI (match_dup 1) (match_dup 2)))]
9066   "ix86_match_ccmode (insn, CCNOmode)
9067    && ix86_binary_operator_ok (XOR, HImode, operands)"
9068   "xor{w}\t{%2, %0|%0, %2}"
9069   [(set_attr "type" "alu")
9070    (set_attr "mode" "HI")])
9072 (define_insn "*xorhi_3"
9073   [(set (reg FLAGS_REG)
9074         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9075                          (match_operand:HI 2 "general_operand" "rim"))
9076                  (const_int 0)))
9077    (clobber (match_scratch:HI 0 "=r"))]
9078   "ix86_match_ccmode (insn, CCNOmode)
9079    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9080   "xor{w}\t{%2, %0|%0, %2}"
9081   [(set_attr "type" "alu")
9082    (set_attr "mode" "HI")])
9084 (define_expand "xorqi3"
9085   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9086         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9087                 (match_operand:QI 2 "general_operand" "")))
9088    (clobber (reg:CC FLAGS_REG))]
9089   "TARGET_QIMODE_MATH"
9090   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9092 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9093 (define_insn "*xorqi_1"
9094   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9095         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9096                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9097    (clobber (reg:CC FLAGS_REG))]
9098   "ix86_binary_operator_ok (XOR, QImode, operands)"
9099   "@
9100    xor{b}\t{%2, %0|%0, %2}
9101    xor{b}\t{%2, %0|%0, %2}
9102    xor{l}\t{%k2, %k0|%k0, %k2}"
9103   [(set_attr "type" "alu")
9104    (set_attr "mode" "QI,QI,SI")])
9106 (define_insn "*xorqi_1_slp"
9107   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9108         (xor:QI (match_dup 0)
9109                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9110    (clobber (reg:CC FLAGS_REG))]
9111   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9112    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9113   "xor{b}\t{%1, %0|%0, %1}"
9114   [(set_attr "type" "alu1")
9115    (set_attr "mode" "QI")])
9117 (define_insn "xorqi_ext_0"
9118   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9119                          (const_int 8)
9120                          (const_int 8))
9121         (xor:SI 
9122           (zero_extract:SI
9123             (match_operand 1 "ext_register_operand" "0")
9124             (const_int 8)
9125             (const_int 8))
9126           (match_operand 2 "const_int_operand" "n")))
9127    (clobber (reg:CC FLAGS_REG))]
9128   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9129   "xor{b}\t{%2, %h0|%h0, %2}"
9130   [(set_attr "type" "alu")
9131    (set_attr "length_immediate" "1")
9132    (set_attr "mode" "QI")])
9134 (define_insn "*xorqi_ext_1"
9135   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9136                          (const_int 8)
9137                          (const_int 8))
9138         (xor:SI 
9139           (zero_extract:SI
9140             (match_operand 1 "ext_register_operand" "0")
9141             (const_int 8)
9142             (const_int 8))
9143           (zero_extend:SI
9144             (match_operand:QI 2 "general_operand" "Qm"))))
9145    (clobber (reg:CC FLAGS_REG))]
9146   "!TARGET_64BIT
9147    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9148   "xor{b}\t{%2, %h0|%h0, %2}"
9149   [(set_attr "type" "alu")
9150    (set_attr "length_immediate" "0")
9151    (set_attr "mode" "QI")])
9153 (define_insn "*xorqi_ext_1_rex64"
9154   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9155                          (const_int 8)
9156                          (const_int 8))
9157         (xor:SI 
9158           (zero_extract:SI
9159             (match_operand 1 "ext_register_operand" "0")
9160             (const_int 8)
9161             (const_int 8))
9162           (zero_extend:SI
9163             (match_operand 2 "ext_register_operand" "Q"))))
9164    (clobber (reg:CC FLAGS_REG))]
9165   "TARGET_64BIT
9166    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167   "xor{b}\t{%2, %h0|%h0, %2}"
9168   [(set_attr "type" "alu")
9169    (set_attr "length_immediate" "0")
9170    (set_attr "mode" "QI")])
9172 (define_insn "*xorqi_ext_2"
9173   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9174                          (const_int 8)
9175                          (const_int 8))
9176         (xor:SI 
9177           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9178                            (const_int 8)
9179                            (const_int 8))
9180           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9181                            (const_int 8)
9182                            (const_int 8))))
9183    (clobber (reg:CC FLAGS_REG))]
9184   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9185   "xor{b}\t{%h2, %h0|%h0, %h2}"
9186   [(set_attr "type" "alu")
9187    (set_attr "length_immediate" "0")
9188    (set_attr "mode" "QI")])
9190 (define_insn "*xorqi_cc_1"
9191   [(set (reg FLAGS_REG)
9192         (compare
9193           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9194                   (match_operand:QI 2 "general_operand" "qim,qi"))
9195           (const_int 0)))
9196    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9197         (xor:QI (match_dup 1) (match_dup 2)))]
9198   "ix86_match_ccmode (insn, CCNOmode)
9199    && ix86_binary_operator_ok (XOR, QImode, operands)"
9200   "xor{b}\t{%2, %0|%0, %2}"
9201   [(set_attr "type" "alu")
9202    (set_attr "mode" "QI")])
9204 (define_insn "*xorqi_2_slp"
9205   [(set (reg FLAGS_REG)
9206         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9207                          (match_operand:QI 1 "general_operand" "qim,qi"))
9208                  (const_int 0)))
9209    (set (strict_low_part (match_dup 0))
9210         (xor:QI (match_dup 0) (match_dup 1)))]
9211   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9212    && ix86_match_ccmode (insn, CCNOmode)
9213    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9214   "xor{b}\t{%1, %0|%0, %1}"
9215   [(set_attr "type" "alu1")
9216    (set_attr "mode" "QI")])
9218 (define_insn "*xorqi_cc_2"
9219   [(set (reg FLAGS_REG)
9220         (compare
9221           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9222                   (match_operand:QI 2 "general_operand" "qim"))
9223           (const_int 0)))
9224    (clobber (match_scratch:QI 0 "=q"))]
9225   "ix86_match_ccmode (insn, CCNOmode)
9226    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9227   "xor{b}\t{%2, %0|%0, %2}"
9228   [(set_attr "type" "alu")
9229    (set_attr "mode" "QI")])
9231 (define_insn "*xorqi_cc_ext_1"
9232   [(set (reg FLAGS_REG)
9233         (compare
9234           (xor:SI
9235             (zero_extract:SI
9236               (match_operand 1 "ext_register_operand" "0")
9237               (const_int 8)
9238               (const_int 8))
9239             (match_operand:QI 2 "general_operand" "qmn"))
9240           (const_int 0)))
9241    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9242                          (const_int 8)
9243                          (const_int 8))
9244         (xor:SI 
9245           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9246           (match_dup 2)))]
9247   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9248   "xor{b}\t{%2, %h0|%h0, %2}"
9249   [(set_attr "type" "alu")
9250    (set_attr "mode" "QI")])
9252 (define_insn "*xorqi_cc_ext_1_rex64"
9253   [(set (reg FLAGS_REG)
9254         (compare
9255           (xor:SI
9256             (zero_extract:SI
9257               (match_operand 1 "ext_register_operand" "0")
9258               (const_int 8)
9259               (const_int 8))
9260             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9261           (const_int 0)))
9262    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9263                          (const_int 8)
9264                          (const_int 8))
9265         (xor:SI 
9266           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9267           (match_dup 2)))]
9268   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9269   "xor{b}\t{%2, %h0|%h0, %2}"
9270   [(set_attr "type" "alu")
9271    (set_attr "mode" "QI")])
9273 (define_expand "xorqi_cc_ext_1"
9274   [(parallel [
9275      (set (reg:CCNO FLAGS_REG)
9276           (compare:CCNO
9277             (xor:SI
9278               (zero_extract:SI
9279                 (match_operand 1 "ext_register_operand" "")
9280                 (const_int 8)
9281                 (const_int 8))
9282               (match_operand:QI 2 "general_operand" ""))
9283             (const_int 0)))
9284      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9285                            (const_int 8)
9286                            (const_int 8))
9287           (xor:SI 
9288             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9289             (match_dup 2)))])]
9290   ""
9291   "")
9293 (define_split
9294   [(set (match_operand 0 "register_operand" "")
9295         (xor (match_operand 1 "register_operand" "")
9296              (match_operand 2 "const_int_operand" "")))
9297    (clobber (reg:CC FLAGS_REG))]
9298    "reload_completed
9299     && QI_REG_P (operands[0])
9300     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9301     && !(INTVAL (operands[2]) & ~(255 << 8))
9302     && GET_MODE (operands[0]) != QImode"
9303   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9304                    (xor:SI (zero_extract:SI (match_dup 1)
9305                                             (const_int 8) (const_int 8))
9306                            (match_dup 2)))
9307               (clobber (reg:CC FLAGS_REG))])]
9308   "operands[0] = gen_lowpart (SImode, operands[0]);
9309    operands[1] = gen_lowpart (SImode, operands[1]);
9310    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9312 ;; Since XOR can be encoded with sign extended immediate, this is only
9313 ;; profitable when 7th bit is set.
9314 (define_split
9315   [(set (match_operand 0 "register_operand" "")
9316         (xor (match_operand 1 "general_operand" "")
9317              (match_operand 2 "const_int_operand" "")))
9318    (clobber (reg:CC FLAGS_REG))]
9319    "reload_completed
9320     && ANY_QI_REG_P (operands[0])
9321     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9322     && !(INTVAL (operands[2]) & ~255)
9323     && (INTVAL (operands[2]) & 128)
9324     && GET_MODE (operands[0]) != QImode"
9325   [(parallel [(set (strict_low_part (match_dup 0))
9326                    (xor:QI (match_dup 1)
9327                            (match_dup 2)))
9328               (clobber (reg:CC FLAGS_REG))])]
9329   "operands[0] = gen_lowpart (QImode, operands[0]);
9330    operands[1] = gen_lowpart (QImode, operands[1]);
9331    operands[2] = gen_lowpart (QImode, operands[2]);")
9333 ;; Negation instructions
9335 (define_expand "negti2"
9336   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9337                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9338               (clobber (reg:CC FLAGS_REG))])]
9339   "TARGET_64BIT"
9340   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9342 (define_insn "*negti2_1"
9343   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9344         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9345    (clobber (reg:CC FLAGS_REG))]
9346   "TARGET_64BIT
9347    && ix86_unary_operator_ok (NEG, TImode, operands)"
9348   "#")
9350 (define_split
9351   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9352         (neg:TI (match_operand:TI 1 "general_operand" "")))
9353    (clobber (reg:CC FLAGS_REG))]
9354   "TARGET_64BIT && reload_completed"
9355   [(parallel
9356     [(set (reg:CCZ FLAGS_REG)
9357           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9358      (set (match_dup 0) (neg:DI (match_dup 2)))])
9359    (parallel
9360     [(set (match_dup 1)
9361           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9362                             (match_dup 3))
9363                    (const_int 0)))
9364      (clobber (reg:CC FLAGS_REG))])
9365    (parallel
9366     [(set (match_dup 1)
9367           (neg:DI (match_dup 1)))
9368      (clobber (reg:CC FLAGS_REG))])]
9369   "split_ti (operands+1, 1, operands+2, operands+3);
9370    split_ti (operands+0, 1, operands+0, operands+1);")
9372 (define_expand "negdi2"
9373   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9374                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9375               (clobber (reg:CC FLAGS_REG))])]
9376   ""
9377   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9379 (define_insn "*negdi2_1"
9380   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9381         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9382    (clobber (reg:CC FLAGS_REG))]
9383   "!TARGET_64BIT
9384    && ix86_unary_operator_ok (NEG, DImode, operands)"
9385   "#")
9387 (define_split
9388   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9389         (neg:DI (match_operand:DI 1 "general_operand" "")))
9390    (clobber (reg:CC FLAGS_REG))]
9391   "!TARGET_64BIT && reload_completed"
9392   [(parallel
9393     [(set (reg:CCZ FLAGS_REG)
9394           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9395      (set (match_dup 0) (neg:SI (match_dup 2)))])
9396    (parallel
9397     [(set (match_dup 1)
9398           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9399                             (match_dup 3))
9400                    (const_int 0)))
9401      (clobber (reg:CC FLAGS_REG))])
9402    (parallel
9403     [(set (match_dup 1)
9404           (neg:SI (match_dup 1)))
9405      (clobber (reg:CC FLAGS_REG))])]
9406   "split_di (operands+1, 1, operands+2, operands+3);
9407    split_di (operands+0, 1, operands+0, operands+1);")
9409 (define_insn "*negdi2_1_rex64"
9410   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9411         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9412    (clobber (reg:CC FLAGS_REG))]
9413   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9414   "neg{q}\t%0"
9415   [(set_attr "type" "negnot")
9416    (set_attr "mode" "DI")])
9418 ;; The problem with neg is that it does not perform (compare x 0),
9419 ;; it really performs (compare 0 x), which leaves us with the zero
9420 ;; flag being the only useful item.
9422 (define_insn "*negdi2_cmpz_rex64"
9423   [(set (reg:CCZ FLAGS_REG)
9424         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9425                      (const_int 0)))
9426    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9427         (neg:DI (match_dup 1)))]
9428   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9429   "neg{q}\t%0"
9430   [(set_attr "type" "negnot")
9431    (set_attr "mode" "DI")])
9434 (define_expand "negsi2"
9435   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9436                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9437               (clobber (reg:CC FLAGS_REG))])]
9438   ""
9439   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9441 (define_insn "*negsi2_1"
9442   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9443         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9444    (clobber (reg:CC FLAGS_REG))]
9445   "ix86_unary_operator_ok (NEG, SImode, operands)"
9446   "neg{l}\t%0"
9447   [(set_attr "type" "negnot")
9448    (set_attr "mode" "SI")])
9450 ;; Combine is quite creative about this pattern.
9451 (define_insn "*negsi2_1_zext"
9452   [(set (match_operand:DI 0 "register_operand" "=r")
9453         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9454                                         (const_int 32)))
9455                      (const_int 32)))
9456    (clobber (reg:CC FLAGS_REG))]
9457   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9458   "neg{l}\t%k0"
9459   [(set_attr "type" "negnot")
9460    (set_attr "mode" "SI")])
9462 ;; The problem with neg is that it does not perform (compare x 0),
9463 ;; it really performs (compare 0 x), which leaves us with the zero
9464 ;; flag being the only useful item.
9466 (define_insn "*negsi2_cmpz"
9467   [(set (reg:CCZ FLAGS_REG)
9468         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9469                      (const_int 0)))
9470    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9471         (neg:SI (match_dup 1)))]
9472   "ix86_unary_operator_ok (NEG, SImode, operands)"
9473   "neg{l}\t%0"
9474   [(set_attr "type" "negnot")
9475    (set_attr "mode" "SI")])
9477 (define_insn "*negsi2_cmpz_zext"
9478   [(set (reg:CCZ FLAGS_REG)
9479         (compare:CCZ (lshiftrt:DI
9480                        (neg:DI (ashift:DI
9481                                  (match_operand:DI 1 "register_operand" "0")
9482                                  (const_int 32)))
9483                        (const_int 32))
9484                      (const_int 0)))
9485    (set (match_operand:DI 0 "register_operand" "=r")
9486         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9487                                         (const_int 32)))
9488                      (const_int 32)))]
9489   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9490   "neg{l}\t%k0"
9491   [(set_attr "type" "negnot")
9492    (set_attr "mode" "SI")])
9494 (define_expand "neghi2"
9495   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9496                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9497               (clobber (reg:CC FLAGS_REG))])]
9498   "TARGET_HIMODE_MATH"
9499   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9501 (define_insn "*neghi2_1"
9502   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9503         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9504    (clobber (reg:CC FLAGS_REG))]
9505   "ix86_unary_operator_ok (NEG, HImode, operands)"
9506   "neg{w}\t%0"
9507   [(set_attr "type" "negnot")
9508    (set_attr "mode" "HI")])
9510 (define_insn "*neghi2_cmpz"
9511   [(set (reg:CCZ FLAGS_REG)
9512         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9513                      (const_int 0)))
9514    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9515         (neg:HI (match_dup 1)))]
9516   "ix86_unary_operator_ok (NEG, HImode, operands)"
9517   "neg{w}\t%0"
9518   [(set_attr "type" "negnot")
9519    (set_attr "mode" "HI")])
9521 (define_expand "negqi2"
9522   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9523                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9524               (clobber (reg:CC FLAGS_REG))])]
9525   "TARGET_QIMODE_MATH"
9526   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9528 (define_insn "*negqi2_1"
9529   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9530         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9531    (clobber (reg:CC FLAGS_REG))]
9532   "ix86_unary_operator_ok (NEG, QImode, operands)"
9533   "neg{b}\t%0"
9534   [(set_attr "type" "negnot")
9535    (set_attr "mode" "QI")])
9537 (define_insn "*negqi2_cmpz"
9538   [(set (reg:CCZ FLAGS_REG)
9539         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9540                      (const_int 0)))
9541    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9542         (neg:QI (match_dup 1)))]
9543   "ix86_unary_operator_ok (NEG, QImode, operands)"
9544   "neg{b}\t%0"
9545   [(set_attr "type" "negnot")
9546    (set_attr "mode" "QI")])
9548 ;; Changing of sign for FP values is doable using integer unit too.
9550 (define_expand "negsf2"
9551   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9552         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9553   "TARGET_80387 || TARGET_SSE_MATH"
9554   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9556 (define_expand "abssf2"
9557   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9558         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9559   "TARGET_80387 || TARGET_SSE_MATH"
9560   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9562 (define_insn "*absnegsf2_mixed"
9563   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9564         (match_operator:SF 3 "absneg_operator"
9565           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9566    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9567    (clobber (reg:CC FLAGS_REG))]
9568   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9569    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9570   "#")
9572 (define_insn "*absnegsf2_sse"
9573   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9574         (match_operator:SF 3 "absneg_operator"
9575           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9576    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9577    (clobber (reg:CC FLAGS_REG))]
9578   "TARGET_SSE_MATH
9579    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9580   "#")
9582 (define_insn "*absnegsf2_i387"
9583   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9584         (match_operator:SF 3 "absneg_operator"
9585           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9586    (use (match_operand 2 "" ""))
9587    (clobber (reg:CC FLAGS_REG))]
9588   "TARGET_80387 && !TARGET_SSE_MATH
9589    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9590   "#")
9592 (define_expand "copysignsf3"
9593   [(match_operand:SF 0 "register_operand" "")
9594    (match_operand:SF 1 "nonmemory_operand" "")
9595    (match_operand:SF 2 "register_operand" "")]
9596   "TARGET_SSE_MATH"
9598   ix86_expand_copysign (operands);
9599   DONE;
9602 (define_insn_and_split "copysignsf3_const"
9603   [(set (match_operand:SF 0 "register_operand"          "=x")
9604         (unspec:SF
9605           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9606            (match_operand:SF 2 "register_operand"       "0")
9607            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9608           UNSPEC_COPYSIGN))]
9609   "TARGET_SSE_MATH"
9610   "#"
9611   "&& reload_completed"
9612   [(const_int 0)]
9614   ix86_split_copysign_const (operands);
9615   DONE;
9618 (define_insn "copysignsf3_var"
9619   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9620         (unspec:SF
9621           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9622            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9623            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9624            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9625           UNSPEC_COPYSIGN))
9626    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9627   "TARGET_SSE_MATH"
9628   "#")
9630 (define_split
9631   [(set (match_operand:SF 0 "register_operand" "")
9632         (unspec:SF
9633           [(match_operand:SF 2 "register_operand" "")
9634            (match_operand:SF 3 "register_operand" "")
9635            (match_operand:V4SF 4 "" "")
9636            (match_operand:V4SF 5 "" "")]
9637           UNSPEC_COPYSIGN))
9638    (clobber (match_scratch:V4SF 1 ""))]
9639   "TARGET_SSE_MATH && reload_completed"
9640   [(const_int 0)]
9642   ix86_split_copysign_var (operands);
9643   DONE;
9646 (define_expand "negdf2"
9647   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9648         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9649   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9650   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9652 (define_expand "absdf2"
9653   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9654         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9655   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9656   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9658 (define_insn "*absnegdf2_mixed"
9659   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9660         (match_operator:DF 3 "absneg_operator"
9661           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9662    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9665    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9666   "#")
9668 (define_insn "*absnegdf2_sse"
9669   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9670         (match_operator:DF 3 "absneg_operator"
9671           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9672    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9673    (clobber (reg:CC FLAGS_REG))]
9674   "TARGET_SSE2 && TARGET_SSE_MATH
9675    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9676   "#")
9678 (define_insn "*absnegdf2_i387"
9679   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9680         (match_operator:DF 3 "absneg_operator"
9681           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9682    (use (match_operand 2 "" ""))
9683    (clobber (reg:CC FLAGS_REG))]
9684   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9685    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9686   "#")
9688 (define_expand "copysigndf3"
9689   [(match_operand:DF 0 "register_operand" "")
9690    (match_operand:DF 1 "nonmemory_operand" "")
9691    (match_operand:DF 2 "register_operand" "")]
9692   "TARGET_SSE2 && TARGET_SSE_MATH"
9694   ix86_expand_copysign (operands);
9695   DONE;
9698 (define_insn_and_split "copysigndf3_const"
9699   [(set (match_operand:DF 0 "register_operand"          "=x")
9700         (unspec:DF
9701           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9702            (match_operand:DF 2 "register_operand"       "0")
9703            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9704           UNSPEC_COPYSIGN))]
9705   "TARGET_SSE2 && TARGET_SSE_MATH"
9706   "#"
9707   "&& reload_completed"
9708   [(const_int 0)]
9710   ix86_split_copysign_const (operands);
9711   DONE;
9714 (define_insn "copysigndf3_var"
9715   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9716         (unspec:DF
9717           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9718            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9719            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9720            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9721           UNSPEC_COPYSIGN))
9722    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9723   "TARGET_SSE2 && TARGET_SSE_MATH"
9724   "#")
9726 (define_split
9727   [(set (match_operand:DF 0 "register_operand" "")
9728         (unspec:DF
9729           [(match_operand:DF 2 "register_operand" "")
9730            (match_operand:DF 3 "register_operand" "")
9731            (match_operand:V2DF 4 "" "")
9732            (match_operand:V2DF 5 "" "")]
9733           UNSPEC_COPYSIGN))
9734    (clobber (match_scratch:V2DF 1 ""))]
9735   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9736   [(const_int 0)]
9738   ix86_split_copysign_var (operands);
9739   DONE;
9742 (define_expand "negxf2"
9743   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9744         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9745   "TARGET_80387"
9746   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9748 (define_expand "absxf2"
9749   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9750         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9751   "TARGET_80387"
9752   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9754 (define_insn "*absnegxf2_i387"
9755   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9756         (match_operator:XF 3 "absneg_operator"
9757           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9758    (use (match_operand 2 "" ""))
9759    (clobber (reg:CC FLAGS_REG))]
9760   "TARGET_80387
9761    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9762   "#")
9764 ;; Splitters for fp abs and neg.
9766 (define_split
9767   [(set (match_operand 0 "fp_register_operand" "")
9768         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9769    (use (match_operand 2 "" ""))
9770    (clobber (reg:CC FLAGS_REG))]
9771   "reload_completed"
9772   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9774 (define_split
9775   [(set (match_operand 0 "register_operand" "")
9776         (match_operator 3 "absneg_operator"
9777           [(match_operand 1 "register_operand" "")]))
9778    (use (match_operand 2 "nonimmediate_operand" ""))
9779    (clobber (reg:CC FLAGS_REG))]
9780   "reload_completed && SSE_REG_P (operands[0])"
9781   [(set (match_dup 0) (match_dup 3))]
9783   enum machine_mode mode = GET_MODE (operands[0]);
9784   enum machine_mode vmode = GET_MODE (operands[2]);
9785   rtx tmp;
9786   
9787   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9788   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9789   if (operands_match_p (operands[0], operands[2]))
9790     {
9791       tmp = operands[1];
9792       operands[1] = operands[2];
9793       operands[2] = tmp;
9794     }
9795   if (GET_CODE (operands[3]) == ABS)
9796     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9797   else
9798     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9799   operands[3] = tmp;
9802 (define_split
9803   [(set (match_operand:SF 0 "register_operand" "")
9804         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9805    (use (match_operand:V4SF 2 "" ""))
9806    (clobber (reg:CC FLAGS_REG))]
9807   "reload_completed"
9808   [(parallel [(set (match_dup 0) (match_dup 1))
9809               (clobber (reg:CC FLAGS_REG))])]
9811   rtx tmp;
9812   operands[0] = gen_lowpart (SImode, operands[0]);
9813   if (GET_CODE (operands[1]) == ABS)
9814     {
9815       tmp = gen_int_mode (0x7fffffff, SImode);
9816       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9817     }
9818   else
9819     {
9820       tmp = gen_int_mode (0x80000000, SImode);
9821       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9822     }
9823   operands[1] = tmp;
9826 (define_split
9827   [(set (match_operand:DF 0 "register_operand" "")
9828         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9829    (use (match_operand 2 "" ""))
9830    (clobber (reg:CC FLAGS_REG))]
9831   "reload_completed"
9832   [(parallel [(set (match_dup 0) (match_dup 1))
9833               (clobber (reg:CC FLAGS_REG))])]
9835   rtx tmp;
9836   if (TARGET_64BIT)
9837     {
9838       tmp = gen_lowpart (DImode, operands[0]);
9839       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9840       operands[0] = tmp;
9842       if (GET_CODE (operands[1]) == ABS)
9843         tmp = const0_rtx;
9844       else
9845         tmp = gen_rtx_NOT (DImode, tmp);
9846     }
9847   else
9848     {
9849       operands[0] = gen_highpart (SImode, operands[0]);
9850       if (GET_CODE (operands[1]) == ABS)
9851         {
9852           tmp = gen_int_mode (0x7fffffff, SImode);
9853           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9854         }
9855       else
9856         {
9857           tmp = gen_int_mode (0x80000000, SImode);
9858           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9859         }
9860     }
9861   operands[1] = tmp;
9864 (define_split
9865   [(set (match_operand:XF 0 "register_operand" "")
9866         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9867    (use (match_operand 2 "" ""))
9868    (clobber (reg:CC FLAGS_REG))]
9869   "reload_completed"
9870   [(parallel [(set (match_dup 0) (match_dup 1))
9871               (clobber (reg:CC FLAGS_REG))])]
9873   rtx tmp;
9874   operands[0] = gen_rtx_REG (SImode,
9875                              true_regnum (operands[0])
9876                              + (TARGET_64BIT ? 1 : 2));
9877   if (GET_CODE (operands[1]) == ABS)
9878     {
9879       tmp = GEN_INT (0x7fff);
9880       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9881     }
9882   else
9883     {
9884       tmp = GEN_INT (0x8000);
9885       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9886     }
9887   operands[1] = tmp;
9890 (define_split
9891   [(set (match_operand 0 "memory_operand" "")
9892         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9893    (use (match_operand 2 "" ""))
9894    (clobber (reg:CC FLAGS_REG))]
9895   "reload_completed"
9896   [(parallel [(set (match_dup 0) (match_dup 1))
9897               (clobber (reg:CC FLAGS_REG))])]
9899   enum machine_mode mode = GET_MODE (operands[0]);
9900   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9901   rtx tmp;
9903   operands[0] = adjust_address (operands[0], QImode, size - 1);
9904   if (GET_CODE (operands[1]) == ABS)
9905     {
9906       tmp = gen_int_mode (0x7f, QImode);
9907       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9908     }
9909   else
9910     {
9911       tmp = gen_int_mode (0x80, QImode);
9912       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9913     }
9914   operands[1] = tmp;
9917 ;; Conditionalize these after reload. If they match before reload, we 
9918 ;; lose the clobber and ability to use integer instructions.
9920 (define_insn "*negsf2_1"
9921   [(set (match_operand:SF 0 "register_operand" "=f")
9922         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9923   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9924   "fchs"
9925   [(set_attr "type" "fsgn")
9926    (set_attr "mode" "SF")])
9928 (define_insn "*negdf2_1"
9929   [(set (match_operand:DF 0 "register_operand" "=f")
9930         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9931   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9932   "fchs"
9933   [(set_attr "type" "fsgn")
9934    (set_attr "mode" "DF")])
9936 (define_insn "*negxf2_1"
9937   [(set (match_operand:XF 0 "register_operand" "=f")
9938         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9939   "TARGET_80387"
9940   "fchs"
9941   [(set_attr "type" "fsgn")
9942    (set_attr "mode" "XF")])
9944 (define_insn "*abssf2_1"
9945   [(set (match_operand:SF 0 "register_operand" "=f")
9946         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9947   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9948   "fabs"
9949   [(set_attr "type" "fsgn")
9950    (set_attr "mode" "SF")])
9952 (define_insn "*absdf2_1"
9953   [(set (match_operand:DF 0 "register_operand" "=f")
9954         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9955   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9956   "fabs"
9957   [(set_attr "type" "fsgn")
9958    (set_attr "mode" "DF")])
9960 (define_insn "*absxf2_1"
9961   [(set (match_operand:XF 0 "register_operand" "=f")
9962         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9963   "TARGET_80387"
9964   "fabs"
9965   [(set_attr "type" "fsgn")
9966    (set_attr "mode" "DF")])
9968 (define_insn "*negextendsfdf2"
9969   [(set (match_operand:DF 0 "register_operand" "=f")
9970         (neg:DF (float_extend:DF
9971                   (match_operand:SF 1 "register_operand" "0"))))]
9972   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9973   "fchs"
9974   [(set_attr "type" "fsgn")
9975    (set_attr "mode" "DF")])
9977 (define_insn "*negextenddfxf2"
9978   [(set (match_operand:XF 0 "register_operand" "=f")
9979         (neg:XF (float_extend:XF
9980                   (match_operand:DF 1 "register_operand" "0"))))]
9981   "TARGET_80387"
9982   "fchs"
9983   [(set_attr "type" "fsgn")
9984    (set_attr "mode" "XF")])
9986 (define_insn "*negextendsfxf2"
9987   [(set (match_operand:XF 0 "register_operand" "=f")
9988         (neg:XF (float_extend:XF
9989                   (match_operand:SF 1 "register_operand" "0"))))]
9990   "TARGET_80387"
9991   "fchs"
9992   [(set_attr "type" "fsgn")
9993    (set_attr "mode" "XF")])
9995 (define_insn "*absextendsfdf2"
9996   [(set (match_operand:DF 0 "register_operand" "=f")
9997         (abs:DF (float_extend:DF
9998                   (match_operand:SF 1 "register_operand" "0"))))]
9999   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10000   "fabs"
10001   [(set_attr "type" "fsgn")
10002    (set_attr "mode" "DF")])
10004 (define_insn "*absextenddfxf2"
10005   [(set (match_operand:XF 0 "register_operand" "=f")
10006         (abs:XF (float_extend:XF
10007           (match_operand:DF 1 "register_operand" "0"))))]
10008   "TARGET_80387"
10009   "fabs"
10010   [(set_attr "type" "fsgn")
10011    (set_attr "mode" "XF")])
10013 (define_insn "*absextendsfxf2"
10014   [(set (match_operand:XF 0 "register_operand" "=f")
10015         (abs:XF (float_extend:XF
10016           (match_operand:SF 1 "register_operand" "0"))))]
10017   "TARGET_80387"
10018   "fabs"
10019   [(set_attr "type" "fsgn")
10020    (set_attr "mode" "XF")])
10022 ;; One complement instructions
10024 (define_expand "one_cmpldi2"
10025   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10026         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10027   "TARGET_64BIT"
10028   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10030 (define_insn "*one_cmpldi2_1_rex64"
10031   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10032         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10033   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10034   "not{q}\t%0"
10035   [(set_attr "type" "negnot")
10036    (set_attr "mode" "DI")])
10038 (define_insn "*one_cmpldi2_2_rex64"
10039   [(set (reg FLAGS_REG)
10040         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10041                  (const_int 0)))
10042    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10043         (not:DI (match_dup 1)))]
10044   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10045    && ix86_unary_operator_ok (NOT, DImode, operands)"
10046   "#"
10047   [(set_attr "type" "alu1")
10048    (set_attr "mode" "DI")])
10050 (define_split
10051   [(set (match_operand 0 "flags_reg_operand" "")
10052         (match_operator 2 "compare_operator"
10053           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10054            (const_int 0)]))
10055    (set (match_operand:DI 1 "nonimmediate_operand" "")
10056         (not:DI (match_dup 3)))]
10057   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10058   [(parallel [(set (match_dup 0)
10059                    (match_op_dup 2
10060                      [(xor:DI (match_dup 3) (const_int -1))
10061                       (const_int 0)]))
10062               (set (match_dup 1)
10063                    (xor:DI (match_dup 3) (const_int -1)))])]
10064   "")
10066 (define_expand "one_cmplsi2"
10067   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10068         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10069   ""
10070   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10072 (define_insn "*one_cmplsi2_1"
10073   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10074         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10075   "ix86_unary_operator_ok (NOT, SImode, operands)"
10076   "not{l}\t%0"
10077   [(set_attr "type" "negnot")
10078    (set_attr "mode" "SI")])
10080 ;; ??? Currently never generated - xor is used instead.
10081 (define_insn "*one_cmplsi2_1_zext"
10082   [(set (match_operand:DI 0 "register_operand" "=r")
10083         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10084   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10085   "not{l}\t%k0"
10086   [(set_attr "type" "negnot")
10087    (set_attr "mode" "SI")])
10089 (define_insn "*one_cmplsi2_2"
10090   [(set (reg FLAGS_REG)
10091         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10092                  (const_int 0)))
10093    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10094         (not:SI (match_dup 1)))]
10095   "ix86_match_ccmode (insn, CCNOmode)
10096    && ix86_unary_operator_ok (NOT, SImode, operands)"
10097   "#"
10098   [(set_attr "type" "alu1")
10099    (set_attr "mode" "SI")])
10101 (define_split
10102   [(set (match_operand 0 "flags_reg_operand" "")
10103         (match_operator 2 "compare_operator"
10104           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10105            (const_int 0)]))
10106    (set (match_operand:SI 1 "nonimmediate_operand" "")
10107         (not:SI (match_dup 3)))]
10108   "ix86_match_ccmode (insn, CCNOmode)"
10109   [(parallel [(set (match_dup 0)
10110                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10111                                     (const_int 0)]))
10112               (set (match_dup 1)
10113                    (xor:SI (match_dup 3) (const_int -1)))])]
10114   "")
10116 ;; ??? Currently never generated - xor is used instead.
10117 (define_insn "*one_cmplsi2_2_zext"
10118   [(set (reg FLAGS_REG)
10119         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10120                  (const_int 0)))
10121    (set (match_operand:DI 0 "register_operand" "=r")
10122         (zero_extend:DI (not:SI (match_dup 1))))]
10123   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10124    && ix86_unary_operator_ok (NOT, SImode, operands)"
10125   "#"
10126   [(set_attr "type" "alu1")
10127    (set_attr "mode" "SI")])
10129 (define_split
10130   [(set (match_operand 0 "flags_reg_operand" "")
10131         (match_operator 2 "compare_operator"
10132           [(not:SI (match_operand:SI 3 "register_operand" ""))
10133            (const_int 0)]))
10134    (set (match_operand:DI 1 "register_operand" "")
10135         (zero_extend:DI (not:SI (match_dup 3))))]
10136   "ix86_match_ccmode (insn, CCNOmode)"
10137   [(parallel [(set (match_dup 0)
10138                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10139                                     (const_int 0)]))
10140               (set (match_dup 1)
10141                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10142   "")
10144 (define_expand "one_cmplhi2"
10145   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10146         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10147   "TARGET_HIMODE_MATH"
10148   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10150 (define_insn "*one_cmplhi2_1"
10151   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10152         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10153   "ix86_unary_operator_ok (NOT, HImode, operands)"
10154   "not{w}\t%0"
10155   [(set_attr "type" "negnot")
10156    (set_attr "mode" "HI")])
10158 (define_insn "*one_cmplhi2_2"
10159   [(set (reg FLAGS_REG)
10160         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10161                  (const_int 0)))
10162    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10163         (not:HI (match_dup 1)))]
10164   "ix86_match_ccmode (insn, CCNOmode)
10165    && ix86_unary_operator_ok (NEG, HImode, operands)"
10166   "#"
10167   [(set_attr "type" "alu1")
10168    (set_attr "mode" "HI")])
10170 (define_split
10171   [(set (match_operand 0 "flags_reg_operand" "")
10172         (match_operator 2 "compare_operator"
10173           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10174            (const_int 0)]))
10175    (set (match_operand:HI 1 "nonimmediate_operand" "")
10176         (not:HI (match_dup 3)))]
10177   "ix86_match_ccmode (insn, CCNOmode)"
10178   [(parallel [(set (match_dup 0)
10179                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10180                                     (const_int 0)]))
10181               (set (match_dup 1)
10182                    (xor:HI (match_dup 3) (const_int -1)))])]
10183   "")
10185 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10186 (define_expand "one_cmplqi2"
10187   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10188         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10189   "TARGET_QIMODE_MATH"
10190   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10192 (define_insn "*one_cmplqi2_1"
10193   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10194         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10195   "ix86_unary_operator_ok (NOT, QImode, operands)"
10196   "@
10197    not{b}\t%0
10198    not{l}\t%k0"
10199   [(set_attr "type" "negnot")
10200    (set_attr "mode" "QI,SI")])
10202 (define_insn "*one_cmplqi2_2"
10203   [(set (reg FLAGS_REG)
10204         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10205                  (const_int 0)))
10206    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10207         (not:QI (match_dup 1)))]
10208   "ix86_match_ccmode (insn, CCNOmode)
10209    && ix86_unary_operator_ok (NOT, QImode, operands)"
10210   "#"
10211   [(set_attr "type" "alu1")
10212    (set_attr "mode" "QI")])
10214 (define_split
10215   [(set (match_operand 0 "flags_reg_operand" "")
10216         (match_operator 2 "compare_operator"
10217           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10218            (const_int 0)]))
10219    (set (match_operand:QI 1 "nonimmediate_operand" "")
10220         (not:QI (match_dup 3)))]
10221   "ix86_match_ccmode (insn, CCNOmode)"
10222   [(parallel [(set (match_dup 0)
10223                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10224                                     (const_int 0)]))
10225               (set (match_dup 1)
10226                    (xor:QI (match_dup 3) (const_int -1)))])]
10227   "")
10229 ;; Arithmetic shift instructions
10231 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10232 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10233 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10234 ;; from the assembler input.
10236 ;; This instruction shifts the target reg/mem as usual, but instead of
10237 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10238 ;; is a left shift double, bits are taken from the high order bits of
10239 ;; reg, else if the insn is a shift right double, bits are taken from the
10240 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10241 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10243 ;; Since sh[lr]d does not change the `reg' operand, that is done
10244 ;; separately, making all shifts emit pairs of shift double and normal
10245 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10246 ;; support a 63 bit shift, each shift where the count is in a reg expands
10247 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10249 ;; If the shift count is a constant, we need never emit more than one
10250 ;; shift pair, instead using moves and sign extension for counts greater
10251 ;; than 31.
10253 (define_expand "ashlti3"
10254   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10255                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10256                               (match_operand:QI 2 "nonmemory_operand" "")))
10257               (clobber (reg:CC FLAGS_REG))])]
10258   "TARGET_64BIT"
10260   if (! immediate_operand (operands[2], QImode))
10261     {
10262       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10263       DONE;
10264     }
10265   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10266   DONE;
10269 (define_insn "ashlti3_1"
10270   [(set (match_operand:TI 0 "register_operand" "=r")
10271         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10272                    (match_operand:QI 2 "register_operand" "c")))
10273    (clobber (match_scratch:DI 3 "=&r"))
10274    (clobber (reg:CC FLAGS_REG))]
10275   "TARGET_64BIT"
10276   "#"
10277   [(set_attr "type" "multi")])
10279 (define_insn "*ashlti3_2"
10280   [(set (match_operand:TI 0 "register_operand" "=r")
10281         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10282                    (match_operand:QI 2 "immediate_operand" "O")))
10283    (clobber (reg:CC FLAGS_REG))]
10284   "TARGET_64BIT"
10285   "#"
10286   [(set_attr "type" "multi")])
10288 (define_split
10289   [(set (match_operand:TI 0 "register_operand" "")
10290         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10291                    (match_operand:QI 2 "register_operand" "")))
10292    (clobber (match_scratch:DI 3 ""))
10293    (clobber (reg:CC FLAGS_REG))]
10294   "TARGET_64BIT && reload_completed"
10295   [(const_int 0)]
10296   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10298 (define_split
10299   [(set (match_operand:TI 0 "register_operand" "")
10300         (ashift:TI (match_operand:TI 1 "register_operand" "")
10301                    (match_operand:QI 2 "immediate_operand" "")))
10302    (clobber (reg:CC FLAGS_REG))]
10303   "TARGET_64BIT && reload_completed"
10304   [(const_int 0)]
10305   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10307 (define_insn "x86_64_shld"
10308   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10309         (ior:DI (ashift:DI (match_dup 0)
10310                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10311                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10312                   (minus:QI (const_int 64) (match_dup 2)))))
10313    (clobber (reg:CC FLAGS_REG))]
10314   "TARGET_64BIT"
10315   "@
10316    shld{q}\t{%2, %1, %0|%0, %1, %2}
10317    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10318   [(set_attr "type" "ishift")
10319    (set_attr "prefix_0f" "1")
10320    (set_attr "mode" "DI")
10321    (set_attr "athlon_decode" "vector")])
10323 (define_expand "x86_64_shift_adj"
10324   [(set (reg:CCZ FLAGS_REG)
10325         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10326                              (const_int 64))
10327                      (const_int 0)))
10328    (set (match_operand:DI 0 "register_operand" "")
10329         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10330                          (match_operand:DI 1 "register_operand" "")
10331                          (match_dup 0)))
10332    (set (match_dup 1)
10333         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10334                          (match_operand:DI 3 "register_operand" "r")
10335                          (match_dup 1)))]
10336   "TARGET_64BIT"
10337   "")
10339 (define_expand "ashldi3"
10340   [(set (match_operand:DI 0 "shiftdi_operand" "")
10341         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10342                    (match_operand:QI 2 "nonmemory_operand" "")))]
10343   ""
10344   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10346 (define_insn "*ashldi3_1_rex64"
10347   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10348         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10349                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10350    (clobber (reg:CC FLAGS_REG))]
10351   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10353   switch (get_attr_type (insn))
10354     {
10355     case TYPE_ALU:
10356       gcc_assert (operands[2] == const1_rtx);
10357       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10358       return "add{q}\t{%0, %0|%0, %0}";
10360     case TYPE_LEA:
10361       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10362       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10363       operands[1] = gen_rtx_MULT (DImode, operands[1],
10364                                   GEN_INT (1 << INTVAL (operands[2])));
10365       return "lea{q}\t{%a1, %0|%0, %a1}";
10367     default:
10368       if (REG_P (operands[2]))
10369         return "sal{q}\t{%b2, %0|%0, %b2}";
10370       else if (operands[2] == const1_rtx
10371                && (TARGET_SHIFT1 || optimize_size))
10372         return "sal{q}\t%0";
10373       else
10374         return "sal{q}\t{%2, %0|%0, %2}";
10375     }
10377   [(set (attr "type")
10378      (cond [(eq_attr "alternative" "1")
10379               (const_string "lea")
10380             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10381                           (const_int 0))
10382                       (match_operand 0 "register_operand" ""))
10383                  (match_operand 2 "const1_operand" ""))
10384               (const_string "alu")
10385            ]
10386            (const_string "ishift")))
10387    (set_attr "mode" "DI")])
10389 ;; Convert lea to the lea pattern to avoid flags dependency.
10390 (define_split
10391   [(set (match_operand:DI 0 "register_operand" "")
10392         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10393                    (match_operand:QI 2 "immediate_operand" "")))
10394    (clobber (reg:CC FLAGS_REG))]
10395   "TARGET_64BIT && reload_completed
10396    && true_regnum (operands[0]) != true_regnum (operands[1])"
10397   [(set (match_dup 0)
10398         (mult:DI (match_dup 1)
10399                  (match_dup 2)))]
10400   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10402 ;; This pattern can't accept a variable shift count, since shifts by
10403 ;; zero don't affect the flags.  We assume that shifts by constant
10404 ;; zero are optimized away.
10405 (define_insn "*ashldi3_cmp_rex64"
10406   [(set (reg FLAGS_REG)
10407         (compare
10408           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10409                      (match_operand:QI 2 "immediate_operand" "e"))
10410           (const_int 0)))
10411    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10412         (ashift:DI (match_dup 1) (match_dup 2)))]
10413   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10414    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10415    && (optimize_size
10416        || !TARGET_PARTIAL_FLAG_REG_STALL
10417        || (operands[2] == const1_rtx
10418            && (TARGET_SHIFT1
10419                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10421   switch (get_attr_type (insn))
10422     {
10423     case TYPE_ALU:
10424       gcc_assert (operands[2] == const1_rtx);
10425       return "add{q}\t{%0, %0|%0, %0}";
10427     default:
10428       if (REG_P (operands[2]))
10429         return "sal{q}\t{%b2, %0|%0, %b2}";
10430       else if (operands[2] == const1_rtx
10431                && (TARGET_SHIFT1 || optimize_size))
10432         return "sal{q}\t%0";
10433       else
10434         return "sal{q}\t{%2, %0|%0, %2}";
10435     }
10437   [(set (attr "type")
10438      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10439                           (const_int 0))
10440                       (match_operand 0 "register_operand" ""))
10441                  (match_operand 2 "const1_operand" ""))
10442               (const_string "alu")
10443            ]
10444            (const_string "ishift")))
10445    (set_attr "mode" "DI")])
10447 (define_insn "*ashldi3_cconly_rex64"
10448   [(set (reg FLAGS_REG)
10449         (compare
10450           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10451                      (match_operand:QI 2 "immediate_operand" "e"))
10452           (const_int 0)))
10453    (clobber (match_scratch:DI 0 "=r"))]
10454   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10455    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10456    && (optimize_size
10457        || !TARGET_PARTIAL_FLAG_REG_STALL
10458        || (operands[2] == const1_rtx
10459            && (TARGET_SHIFT1
10460                || TARGET_DOUBLE_WITH_ADD)))"
10462   switch (get_attr_type (insn))
10463     {
10464     case TYPE_ALU:
10465       gcc_assert (operands[2] == const1_rtx);
10466       return "add{q}\t{%0, %0|%0, %0}";
10468     default:
10469       if (REG_P (operands[2]))
10470         return "sal{q}\t{%b2, %0|%0, %b2}";
10471       else if (operands[2] == const1_rtx
10472                && (TARGET_SHIFT1 || optimize_size))
10473         return "sal{q}\t%0";
10474       else
10475         return "sal{q}\t{%2, %0|%0, %2}";
10476     }
10478   [(set (attr "type")
10479      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10480                           (const_int 0))
10481                       (match_operand 0 "register_operand" ""))
10482                  (match_operand 2 "const1_operand" ""))
10483               (const_string "alu")
10484            ]
10485            (const_string "ishift")))
10486    (set_attr "mode" "DI")])
10488 (define_insn "*ashldi3_1"
10489   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10490         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10491                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10492    (clobber (reg:CC FLAGS_REG))]
10493   "!TARGET_64BIT"
10494   "#"
10495   [(set_attr "type" "multi")])
10497 ;; By default we don't ask for a scratch register, because when DImode
10498 ;; values are manipulated, registers are already at a premium.  But if
10499 ;; we have one handy, we won't turn it away.
10500 (define_peephole2
10501   [(match_scratch:SI 3 "r")
10502    (parallel [(set (match_operand:DI 0 "register_operand" "")
10503                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10504                               (match_operand:QI 2 "nonmemory_operand" "")))
10505               (clobber (reg:CC FLAGS_REG))])
10506    (match_dup 3)]
10507   "!TARGET_64BIT && TARGET_CMOVE"
10508   [(const_int 0)]
10509   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10511 (define_split
10512   [(set (match_operand:DI 0 "register_operand" "")
10513         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10514                    (match_operand:QI 2 "nonmemory_operand" "")))
10515    (clobber (reg:CC FLAGS_REG))]
10516   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10517                      ? flow2_completed : reload_completed)"
10518   [(const_int 0)]
10519   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10521 (define_insn "x86_shld_1"
10522   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10523         (ior:SI (ashift:SI (match_dup 0)
10524                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10525                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10526                   (minus:QI (const_int 32) (match_dup 2)))))
10527    (clobber (reg:CC FLAGS_REG))]
10528   ""
10529   "@
10530    shld{l}\t{%2, %1, %0|%0, %1, %2}
10531    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10532   [(set_attr "type" "ishift")
10533    (set_attr "prefix_0f" "1")
10534    (set_attr "mode" "SI")
10535    (set_attr "pent_pair" "np")
10536    (set_attr "athlon_decode" "vector")])
10538 (define_expand "x86_shift_adj_1"
10539   [(set (reg:CCZ FLAGS_REG)
10540         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10541                              (const_int 32))
10542                      (const_int 0)))
10543    (set (match_operand:SI 0 "register_operand" "")
10544         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10545                          (match_operand:SI 1 "register_operand" "")
10546                          (match_dup 0)))
10547    (set (match_dup 1)
10548         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10549                          (match_operand:SI 3 "register_operand" "r")
10550                          (match_dup 1)))]
10551   "TARGET_CMOVE"
10552   "")
10554 (define_expand "x86_shift_adj_2"
10555   [(use (match_operand:SI 0 "register_operand" ""))
10556    (use (match_operand:SI 1 "register_operand" ""))
10557    (use (match_operand:QI 2 "register_operand" ""))]
10558   ""
10560   rtx label = gen_label_rtx ();
10561   rtx tmp;
10563   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10565   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10566   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10567   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10568                               gen_rtx_LABEL_REF (VOIDmode, label),
10569                               pc_rtx);
10570   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10571   JUMP_LABEL (tmp) = label;
10573   emit_move_insn (operands[0], operands[1]);
10574   ix86_expand_clear (operands[1]);
10576   emit_label (label);
10577   LABEL_NUSES (label) = 1;
10579   DONE;
10582 (define_expand "ashlsi3"
10583   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10584         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10585                    (match_operand:QI 2 "nonmemory_operand" "")))
10586    (clobber (reg:CC FLAGS_REG))]
10587   ""
10588   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10590 (define_insn "*ashlsi3_1"
10591   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10592         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10593                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10594    (clobber (reg:CC FLAGS_REG))]
10595   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10597   switch (get_attr_type (insn))
10598     {
10599     case TYPE_ALU:
10600       gcc_assert (operands[2] == const1_rtx);
10601       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10602       return "add{l}\t{%0, %0|%0, %0}";
10604     case TYPE_LEA:
10605       return "#";
10607     default:
10608       if (REG_P (operands[2]))
10609         return "sal{l}\t{%b2, %0|%0, %b2}";
10610       else if (operands[2] == const1_rtx
10611                && (TARGET_SHIFT1 || optimize_size))
10612         return "sal{l}\t%0";
10613       else
10614         return "sal{l}\t{%2, %0|%0, %2}";
10615     }
10617   [(set (attr "type")
10618      (cond [(eq_attr "alternative" "1")
10619               (const_string "lea")
10620             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10621                           (const_int 0))
10622                       (match_operand 0 "register_operand" ""))
10623                  (match_operand 2 "const1_operand" ""))
10624               (const_string "alu")
10625            ]
10626            (const_string "ishift")))
10627    (set_attr "mode" "SI")])
10629 ;; Convert lea to the lea pattern to avoid flags dependency.
10630 (define_split
10631   [(set (match_operand 0 "register_operand" "")
10632         (ashift (match_operand 1 "index_register_operand" "")
10633                 (match_operand:QI 2 "const_int_operand" "")))
10634    (clobber (reg:CC FLAGS_REG))]
10635   "reload_completed
10636    && true_regnum (operands[0]) != true_regnum (operands[1])
10637    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10638   [(const_int 0)]
10640   rtx pat;
10641   enum machine_mode mode = GET_MODE (operands[0]);
10643   if (GET_MODE_SIZE (mode) < 4)
10644     operands[0] = gen_lowpart (SImode, operands[0]);
10645   if (mode != Pmode)
10646     operands[1] = gen_lowpart (Pmode, operands[1]);
10647   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10649   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10650   if (Pmode != SImode)
10651     pat = gen_rtx_SUBREG (SImode, pat, 0);
10652   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10653   DONE;
10656 ;; Rare case of shifting RSP is handled by generating move and shift
10657 (define_split
10658   [(set (match_operand 0 "register_operand" "")
10659         (ashift (match_operand 1 "register_operand" "")
10660                 (match_operand:QI 2 "const_int_operand" "")))
10661    (clobber (reg:CC FLAGS_REG))]
10662   "reload_completed
10663    && true_regnum (operands[0]) != true_regnum (operands[1])"
10664   [(const_int 0)]
10666   rtx pat, clob;
10667   emit_move_insn (operands[0], operands[1]);
10668   pat = gen_rtx_SET (VOIDmode, operands[0],
10669                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10670                                      operands[0], operands[2]));
10671   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10672   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10673   DONE;
10676 (define_insn "*ashlsi3_1_zext"
10677   [(set (match_operand:DI 0 "register_operand" "=r,r")
10678         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10679                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10680    (clobber (reg:CC FLAGS_REG))]
10681   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10683   switch (get_attr_type (insn))
10684     {
10685     case TYPE_ALU:
10686       gcc_assert (operands[2] == const1_rtx);
10687       return "add{l}\t{%k0, %k0|%k0, %k0}";
10689     case TYPE_LEA:
10690       return "#";
10692     default:
10693       if (REG_P (operands[2]))
10694         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10695       else if (operands[2] == const1_rtx
10696                && (TARGET_SHIFT1 || optimize_size))
10697         return "sal{l}\t%k0";
10698       else
10699         return "sal{l}\t{%2, %k0|%k0, %2}";
10700     }
10702   [(set (attr "type")
10703      (cond [(eq_attr "alternative" "1")
10704               (const_string "lea")
10705             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10706                      (const_int 0))
10707                  (match_operand 2 "const1_operand" ""))
10708               (const_string "alu")
10709            ]
10710            (const_string "ishift")))
10711    (set_attr "mode" "SI")])
10713 ;; Convert lea to the lea pattern to avoid flags dependency.
10714 (define_split
10715   [(set (match_operand:DI 0 "register_operand" "")
10716         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10717                                 (match_operand:QI 2 "const_int_operand" ""))))
10718    (clobber (reg:CC FLAGS_REG))]
10719   "TARGET_64BIT && reload_completed
10720    && true_regnum (operands[0]) != true_regnum (operands[1])"
10721   [(set (match_dup 0) (zero_extend:DI
10722                         (subreg:SI (mult:SI (match_dup 1)
10723                                             (match_dup 2)) 0)))]
10725   operands[1] = gen_lowpart (Pmode, operands[1]);
10726   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10729 ;; This pattern can't accept a variable shift count, since shifts by
10730 ;; zero don't affect the flags.  We assume that shifts by constant
10731 ;; zero are optimized away.
10732 (define_insn "*ashlsi3_cmp"
10733   [(set (reg FLAGS_REG)
10734         (compare
10735           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10736                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10737           (const_int 0)))
10738    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10739         (ashift:SI (match_dup 1) (match_dup 2)))]
10740   "ix86_match_ccmode (insn, CCGOCmode)
10741    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10742    && (optimize_size
10743        || !TARGET_PARTIAL_FLAG_REG_STALL
10744        || (operands[2] == const1_rtx
10745            && (TARGET_SHIFT1
10746                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10748   switch (get_attr_type (insn))
10749     {
10750     case TYPE_ALU:
10751       gcc_assert (operands[2] == const1_rtx);
10752       return "add{l}\t{%0, %0|%0, %0}";
10754     default:
10755       if (REG_P (operands[2]))
10756         return "sal{l}\t{%b2, %0|%0, %b2}";
10757       else if (operands[2] == const1_rtx
10758                && (TARGET_SHIFT1 || optimize_size))
10759         return "sal{l}\t%0";
10760       else
10761         return "sal{l}\t{%2, %0|%0, %2}";
10762     }
10764   [(set (attr "type")
10765      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10766                           (const_int 0))
10767                       (match_operand 0 "register_operand" ""))
10768                  (match_operand 2 "const1_operand" ""))
10769               (const_string "alu")
10770            ]
10771            (const_string "ishift")))
10772    (set_attr "mode" "SI")])
10774 (define_insn "*ashlsi3_cconly"
10775   [(set (reg FLAGS_REG)
10776         (compare
10777           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10778                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10779           (const_int 0)))
10780    (clobber (match_scratch:SI 0 "=r"))]
10781   "ix86_match_ccmode (insn, CCGOCmode)
10782    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10783    && (optimize_size
10784        || !TARGET_PARTIAL_FLAG_REG_STALL
10785        || (operands[2] == const1_rtx
10786            && (TARGET_SHIFT1
10787                || TARGET_DOUBLE_WITH_ADD)))"
10789   switch (get_attr_type (insn))
10790     {
10791     case TYPE_ALU:
10792       gcc_assert (operands[2] == const1_rtx);
10793       return "add{l}\t{%0, %0|%0, %0}";
10795     default:
10796       if (REG_P (operands[2]))
10797         return "sal{l}\t{%b2, %0|%0, %b2}";
10798       else if (operands[2] == const1_rtx
10799                && (TARGET_SHIFT1 || optimize_size))
10800         return "sal{l}\t%0";
10801       else
10802         return "sal{l}\t{%2, %0|%0, %2}";
10803     }
10805   [(set (attr "type")
10806      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10807                           (const_int 0))
10808                       (match_operand 0 "register_operand" ""))
10809                  (match_operand 2 "const1_operand" ""))
10810               (const_string "alu")
10811            ]
10812            (const_string "ishift")))
10813    (set_attr "mode" "SI")])
10815 (define_insn "*ashlsi3_cmp_zext"
10816   [(set (reg FLAGS_REG)
10817         (compare
10818           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10819                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10820           (const_int 0)))
10821    (set (match_operand:DI 0 "register_operand" "=r")
10822         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10823   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10824    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10825    && (optimize_size
10826        || !TARGET_PARTIAL_FLAG_REG_STALL
10827        || (operands[2] == const1_rtx
10828            && (TARGET_SHIFT1
10829                || TARGET_DOUBLE_WITH_ADD)))"
10831   switch (get_attr_type (insn))
10832     {
10833     case TYPE_ALU:
10834       gcc_assert (operands[2] == const1_rtx);
10835       return "add{l}\t{%k0, %k0|%k0, %k0}";
10837     default:
10838       if (REG_P (operands[2]))
10839         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10840       else if (operands[2] == const1_rtx
10841                && (TARGET_SHIFT1 || optimize_size))
10842         return "sal{l}\t%k0";
10843       else
10844         return "sal{l}\t{%2, %k0|%k0, %2}";
10845     }
10847   [(set (attr "type")
10848      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10849                      (const_int 0))
10850                  (match_operand 2 "const1_operand" ""))
10851               (const_string "alu")
10852            ]
10853            (const_string "ishift")))
10854    (set_attr "mode" "SI")])
10856 (define_expand "ashlhi3"
10857   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10858         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10859                    (match_operand:QI 2 "nonmemory_operand" "")))
10860    (clobber (reg:CC FLAGS_REG))]
10861   "TARGET_HIMODE_MATH"
10862   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10864 (define_insn "*ashlhi3_1_lea"
10865   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10866         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10867                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10868    (clobber (reg:CC FLAGS_REG))]
10869   "!TARGET_PARTIAL_REG_STALL
10870    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10872   switch (get_attr_type (insn))
10873     {
10874     case TYPE_LEA:
10875       return "#";
10876     case TYPE_ALU:
10877       gcc_assert (operands[2] == const1_rtx);
10878       return "add{w}\t{%0, %0|%0, %0}";
10880     default:
10881       if (REG_P (operands[2]))
10882         return "sal{w}\t{%b2, %0|%0, %b2}";
10883       else if (operands[2] == const1_rtx
10884                && (TARGET_SHIFT1 || optimize_size))
10885         return "sal{w}\t%0";
10886       else
10887         return "sal{w}\t{%2, %0|%0, %2}";
10888     }
10890   [(set (attr "type")
10891      (cond [(eq_attr "alternative" "1")
10892               (const_string "lea")
10893             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10894                           (const_int 0))
10895                       (match_operand 0 "register_operand" ""))
10896                  (match_operand 2 "const1_operand" ""))
10897               (const_string "alu")
10898            ]
10899            (const_string "ishift")))
10900    (set_attr "mode" "HI,SI")])
10902 (define_insn "*ashlhi3_1"
10903   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10904         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10905                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10906    (clobber (reg:CC FLAGS_REG))]
10907   "TARGET_PARTIAL_REG_STALL
10908    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10910   switch (get_attr_type (insn))
10911     {
10912     case TYPE_ALU:
10913       gcc_assert (operands[2] == const1_rtx);
10914       return "add{w}\t{%0, %0|%0, %0}";
10916     default:
10917       if (REG_P (operands[2]))
10918         return "sal{w}\t{%b2, %0|%0, %b2}";
10919       else if (operands[2] == const1_rtx
10920                && (TARGET_SHIFT1 || optimize_size))
10921         return "sal{w}\t%0";
10922       else
10923         return "sal{w}\t{%2, %0|%0, %2}";
10924     }
10926   [(set (attr "type")
10927      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10928                           (const_int 0))
10929                       (match_operand 0 "register_operand" ""))
10930                  (match_operand 2 "const1_operand" ""))
10931               (const_string "alu")
10932            ]
10933            (const_string "ishift")))
10934    (set_attr "mode" "HI")])
10936 ;; This pattern can't accept a variable shift count, since shifts by
10937 ;; zero don't affect the flags.  We assume that shifts by constant
10938 ;; zero are optimized away.
10939 (define_insn "*ashlhi3_cmp"
10940   [(set (reg FLAGS_REG)
10941         (compare
10942           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10943                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10944           (const_int 0)))
10945    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10946         (ashift:HI (match_dup 1) (match_dup 2)))]
10947   "ix86_match_ccmode (insn, CCGOCmode)
10948    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10949    && (optimize_size
10950        || !TARGET_PARTIAL_FLAG_REG_STALL
10951        || (operands[2] == const1_rtx
10952            && (TARGET_SHIFT1
10953                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10955   switch (get_attr_type (insn))
10956     {
10957     case TYPE_ALU:
10958       gcc_assert (operands[2] == const1_rtx);
10959       return "add{w}\t{%0, %0|%0, %0}";
10961     default:
10962       if (REG_P (operands[2]))
10963         return "sal{w}\t{%b2, %0|%0, %b2}";
10964       else if (operands[2] == const1_rtx
10965                && (TARGET_SHIFT1 || optimize_size))
10966         return "sal{w}\t%0";
10967       else
10968         return "sal{w}\t{%2, %0|%0, %2}";
10969     }
10971   [(set (attr "type")
10972      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10973                           (const_int 0))
10974                       (match_operand 0 "register_operand" ""))
10975                  (match_operand 2 "const1_operand" ""))
10976               (const_string "alu")
10977            ]
10978            (const_string "ishift")))
10979    (set_attr "mode" "HI")])
10981 (define_insn "*ashlhi3_cconly"
10982   [(set (reg FLAGS_REG)
10983         (compare
10984           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10985                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10986           (const_int 0)))
10987    (clobber (match_scratch:HI 0 "=r"))]
10988   "ix86_match_ccmode (insn, CCGOCmode)
10989    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10990    && (optimize_size
10991        || !TARGET_PARTIAL_FLAG_REG_STALL
10992        || (operands[2] == const1_rtx
10993            && (TARGET_SHIFT1
10994                || TARGET_DOUBLE_WITH_ADD)))"
10996   switch (get_attr_type (insn))
10997     {
10998     case TYPE_ALU:
10999       gcc_assert (operands[2] == const1_rtx);
11000       return "add{w}\t{%0, %0|%0, %0}";
11002     default:
11003       if (REG_P (operands[2]))
11004         return "sal{w}\t{%b2, %0|%0, %b2}";
11005       else if (operands[2] == const1_rtx
11006                && (TARGET_SHIFT1 || optimize_size))
11007         return "sal{w}\t%0";
11008       else
11009         return "sal{w}\t{%2, %0|%0, %2}";
11010     }
11012   [(set (attr "type")
11013      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014                           (const_int 0))
11015                       (match_operand 0 "register_operand" ""))
11016                  (match_operand 2 "const1_operand" ""))
11017               (const_string "alu")
11018            ]
11019            (const_string "ishift")))
11020    (set_attr "mode" "HI")])
11022 (define_expand "ashlqi3"
11023   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11024         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11025                    (match_operand:QI 2 "nonmemory_operand" "")))
11026    (clobber (reg:CC FLAGS_REG))]
11027   "TARGET_QIMODE_MATH"
11028   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11030 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11032 (define_insn "*ashlqi3_1_lea"
11033   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11034         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11035                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11036    (clobber (reg:CC FLAGS_REG))]
11037   "!TARGET_PARTIAL_REG_STALL
11038    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11040   switch (get_attr_type (insn))
11041     {
11042     case TYPE_LEA:
11043       return "#";
11044     case TYPE_ALU:
11045       gcc_assert (operands[2] == const1_rtx);
11046       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11047         return "add{l}\t{%k0, %k0|%k0, %k0}";
11048       else
11049         return "add{b}\t{%0, %0|%0, %0}";
11051     default:
11052       if (REG_P (operands[2]))
11053         {
11054           if (get_attr_mode (insn) == MODE_SI)
11055             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11056           else
11057             return "sal{b}\t{%b2, %0|%0, %b2}";
11058         }
11059       else if (operands[2] == const1_rtx
11060                && (TARGET_SHIFT1 || optimize_size))
11061         {
11062           if (get_attr_mode (insn) == MODE_SI)
11063             return "sal{l}\t%0";
11064           else
11065             return "sal{b}\t%0";
11066         }
11067       else
11068         {
11069           if (get_attr_mode (insn) == MODE_SI)
11070             return "sal{l}\t{%2, %k0|%k0, %2}";
11071           else
11072             return "sal{b}\t{%2, %0|%0, %2}";
11073         }
11074     }
11076   [(set (attr "type")
11077      (cond [(eq_attr "alternative" "2")
11078               (const_string "lea")
11079             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11080                           (const_int 0))
11081                       (match_operand 0 "register_operand" ""))
11082                  (match_operand 2 "const1_operand" ""))
11083               (const_string "alu")
11084            ]
11085            (const_string "ishift")))
11086    (set_attr "mode" "QI,SI,SI")])
11088 (define_insn "*ashlqi3_1"
11089   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11090         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11091                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11092    (clobber (reg:CC FLAGS_REG))]
11093   "TARGET_PARTIAL_REG_STALL
11094    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11096   switch (get_attr_type (insn))
11097     {
11098     case TYPE_ALU:
11099       gcc_assert (operands[2] == const1_rtx);
11100       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11101         return "add{l}\t{%k0, %k0|%k0, %k0}";
11102       else
11103         return "add{b}\t{%0, %0|%0, %0}";
11105     default:
11106       if (REG_P (operands[2]))
11107         {
11108           if (get_attr_mode (insn) == MODE_SI)
11109             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11110           else
11111             return "sal{b}\t{%b2, %0|%0, %b2}";
11112         }
11113       else if (operands[2] == const1_rtx
11114                && (TARGET_SHIFT1 || optimize_size))
11115         {
11116           if (get_attr_mode (insn) == MODE_SI)
11117             return "sal{l}\t%0";
11118           else
11119             return "sal{b}\t%0";
11120         }
11121       else
11122         {
11123           if (get_attr_mode (insn) == MODE_SI)
11124             return "sal{l}\t{%2, %k0|%k0, %2}";
11125           else
11126             return "sal{b}\t{%2, %0|%0, %2}";
11127         }
11128     }
11130   [(set (attr "type")
11131      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11132                           (const_int 0))
11133                       (match_operand 0 "register_operand" ""))
11134                  (match_operand 2 "const1_operand" ""))
11135               (const_string "alu")
11136            ]
11137            (const_string "ishift")))
11138    (set_attr "mode" "QI,SI")])
11140 ;; This pattern can't accept a variable shift count, since shifts by
11141 ;; zero don't affect the flags.  We assume that shifts by constant
11142 ;; zero are optimized away.
11143 (define_insn "*ashlqi3_cmp"
11144   [(set (reg FLAGS_REG)
11145         (compare
11146           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11147                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11148           (const_int 0)))
11149    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11150         (ashift:QI (match_dup 1) (match_dup 2)))]
11151   "ix86_match_ccmode (insn, CCGOCmode)
11152    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11153    && (optimize_size
11154        || !TARGET_PARTIAL_FLAG_REG_STALL
11155        || (operands[2] == const1_rtx
11156            && (TARGET_SHIFT1
11157                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11159   switch (get_attr_type (insn))
11160     {
11161     case TYPE_ALU:
11162       gcc_assert (operands[2] == const1_rtx);
11163       return "add{b}\t{%0, %0|%0, %0}";
11165     default:
11166       if (REG_P (operands[2]))
11167         return "sal{b}\t{%b2, %0|%0, %b2}";
11168       else if (operands[2] == const1_rtx
11169                && (TARGET_SHIFT1 || optimize_size))
11170         return "sal{b}\t%0";
11171       else
11172         return "sal{b}\t{%2, %0|%0, %2}";
11173     }
11175   [(set (attr "type")
11176      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11177                           (const_int 0))
11178                       (match_operand 0 "register_operand" ""))
11179                  (match_operand 2 "const1_operand" ""))
11180               (const_string "alu")
11181            ]
11182            (const_string "ishift")))
11183    (set_attr "mode" "QI")])
11185 (define_insn "*ashlqi3_cconly"
11186   [(set (reg FLAGS_REG)
11187         (compare
11188           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11189                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11190           (const_int 0)))
11191    (clobber (match_scratch:QI 0 "=q"))]
11192   "ix86_match_ccmode (insn, CCGOCmode)
11193    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11194    && (optimize_size
11195        || !TARGET_PARTIAL_FLAG_REG_STALL
11196        || (operands[2] == const1_rtx
11197            && (TARGET_SHIFT1
11198                || TARGET_DOUBLE_WITH_ADD)))"
11200   switch (get_attr_type (insn))
11201     {
11202     case TYPE_ALU:
11203       gcc_assert (operands[2] == const1_rtx);
11204       return "add{b}\t{%0, %0|%0, %0}";
11206     default:
11207       if (REG_P (operands[2]))
11208         return "sal{b}\t{%b2, %0|%0, %b2}";
11209       else if (operands[2] == const1_rtx
11210                && (TARGET_SHIFT1 || optimize_size))
11211         return "sal{b}\t%0";
11212       else
11213         return "sal{b}\t{%2, %0|%0, %2}";
11214     }
11216   [(set (attr "type")
11217      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11218                           (const_int 0))
11219                       (match_operand 0 "register_operand" ""))
11220                  (match_operand 2 "const1_operand" ""))
11221               (const_string "alu")
11222            ]
11223            (const_string "ishift")))
11224    (set_attr "mode" "QI")])
11226 ;; See comment above `ashldi3' about how this works.
11228 (define_expand "ashrti3"
11229   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11230                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11231                                 (match_operand:QI 2 "nonmemory_operand" "")))
11232               (clobber (reg:CC FLAGS_REG))])]
11233   "TARGET_64BIT"
11235   if (! immediate_operand (operands[2], QImode))
11236     {
11237       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11238       DONE;
11239     }
11240   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11241   DONE;
11244 (define_insn "ashrti3_1"
11245   [(set (match_operand:TI 0 "register_operand" "=r")
11246         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11247                      (match_operand:QI 2 "register_operand" "c")))
11248    (clobber (match_scratch:DI 3 "=&r"))
11249    (clobber (reg:CC FLAGS_REG))]
11250   "TARGET_64BIT"
11251   "#"
11252   [(set_attr "type" "multi")])
11254 (define_insn "*ashrti3_2"
11255   [(set (match_operand:TI 0 "register_operand" "=r")
11256         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11257                      (match_operand:QI 2 "immediate_operand" "O")))
11258    (clobber (reg:CC FLAGS_REG))]
11259   "TARGET_64BIT"
11260   "#"
11261   [(set_attr "type" "multi")])
11263 (define_split
11264   [(set (match_operand:TI 0 "register_operand" "")
11265         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11266                      (match_operand:QI 2 "register_operand" "")))
11267    (clobber (match_scratch:DI 3 ""))
11268    (clobber (reg:CC FLAGS_REG))]
11269   "TARGET_64BIT && reload_completed"
11270   [(const_int 0)]
11271   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11273 (define_split
11274   [(set (match_operand:TI 0 "register_operand" "")
11275         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11276                      (match_operand:QI 2 "immediate_operand" "")))
11277    (clobber (reg:CC FLAGS_REG))]
11278   "TARGET_64BIT && reload_completed"
11279   [(const_int 0)]
11280   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11282 (define_insn "x86_64_shrd"
11283   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11284         (ior:DI (ashiftrt:DI (match_dup 0)
11285                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11286                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11287                   (minus:QI (const_int 64) (match_dup 2)))))
11288    (clobber (reg:CC FLAGS_REG))]
11289   "TARGET_64BIT"
11290   "@
11291    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11292    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11293   [(set_attr "type" "ishift")
11294    (set_attr "prefix_0f" "1")
11295    (set_attr "mode" "DI")
11296    (set_attr "athlon_decode" "vector")])
11298 (define_expand "ashrdi3"
11299   [(set (match_operand:DI 0 "shiftdi_operand" "")
11300         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11301                      (match_operand:QI 2 "nonmemory_operand" "")))]
11302   ""
11303   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11305 (define_insn "*ashrdi3_63_rex64"
11306   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11307         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11308                      (match_operand:DI 2 "const_int_operand" "i,i")))
11309    (clobber (reg:CC FLAGS_REG))]
11310   "TARGET_64BIT && INTVAL (operands[2]) == 63
11311    && (TARGET_USE_CLTD || optimize_size)
11312    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11313   "@
11314    {cqto|cqo}
11315    sar{q}\t{%2, %0|%0, %2}"
11316   [(set_attr "type" "imovx,ishift")
11317    (set_attr "prefix_0f" "0,*")
11318    (set_attr "length_immediate" "0,*")
11319    (set_attr "modrm" "0,1")
11320    (set_attr "mode" "DI")])
11322 (define_insn "*ashrdi3_1_one_bit_rex64"
11323   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11324         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11325                      (match_operand:QI 2 "const1_operand" "")))
11326    (clobber (reg:CC FLAGS_REG))]
11327   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11328    && (TARGET_SHIFT1 || optimize_size)"
11329   "sar{q}\t%0"
11330   [(set_attr "type" "ishift")
11331    (set (attr "length") 
11332      (if_then_else (match_operand:DI 0 "register_operand" "") 
11333         (const_string "2")
11334         (const_string "*")))])
11336 (define_insn "*ashrdi3_1_rex64"
11337   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11338         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11339                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11340    (clobber (reg:CC FLAGS_REG))]
11341   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11342   "@
11343    sar{q}\t{%2, %0|%0, %2}
11344    sar{q}\t{%b2, %0|%0, %b2}"
11345   [(set_attr "type" "ishift")
11346    (set_attr "mode" "DI")])
11348 ;; This pattern can't accept a variable shift count, since shifts by
11349 ;; zero don't affect the flags.  We assume that shifts by constant
11350 ;; zero are optimized away.
11351 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11352   [(set (reg FLAGS_REG)
11353         (compare
11354           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11355                        (match_operand:QI 2 "const1_operand" ""))
11356           (const_int 0)))
11357    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11358         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11359   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11360    && (TARGET_SHIFT1 || optimize_size)
11361    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11362   "sar{q}\t%0"
11363   [(set_attr "type" "ishift")
11364    (set (attr "length") 
11365      (if_then_else (match_operand:DI 0 "register_operand" "") 
11366         (const_string "2")
11367         (const_string "*")))])
11369 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11370   [(set (reg FLAGS_REG)
11371         (compare
11372           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11373                        (match_operand:QI 2 "const1_operand" ""))
11374           (const_int 0)))
11375    (clobber (match_scratch:DI 0 "=r"))]
11376   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11377    && (TARGET_SHIFT1 || optimize_size)
11378    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11379   "sar{q}\t%0"
11380   [(set_attr "type" "ishift")
11381    (set_attr "length" "2")])
11383 ;; This pattern can't accept a variable shift count, since shifts by
11384 ;; zero don't affect the flags.  We assume that shifts by constant
11385 ;; zero are optimized away.
11386 (define_insn "*ashrdi3_cmp_rex64"
11387   [(set (reg FLAGS_REG)
11388         (compare
11389           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11390                        (match_operand:QI 2 "const_int_operand" "n"))
11391           (const_int 0)))
11392    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11393         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11394   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11395    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11396    && (optimize_size
11397        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11398   "sar{q}\t{%2, %0|%0, %2}"
11399   [(set_attr "type" "ishift")
11400    (set_attr "mode" "DI")])
11402 (define_insn "*ashrdi3_cconly_rex64"
11403   [(set (reg FLAGS_REG)
11404         (compare
11405           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11406                        (match_operand:QI 2 "const_int_operand" "n"))
11407           (const_int 0)))
11408    (clobber (match_scratch:DI 0 "=r"))]
11409   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11410    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11411    && (optimize_size
11412        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11413   "sar{q}\t{%2, %0|%0, %2}"
11414   [(set_attr "type" "ishift")
11415    (set_attr "mode" "DI")])
11417 (define_insn "*ashrdi3_1"
11418   [(set (match_operand:DI 0 "register_operand" "=r")
11419         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11420                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11421    (clobber (reg:CC FLAGS_REG))]
11422   "!TARGET_64BIT"
11423   "#"
11424   [(set_attr "type" "multi")])
11426 ;; By default we don't ask for a scratch register, because when DImode
11427 ;; values are manipulated, registers are already at a premium.  But if
11428 ;; we have one handy, we won't turn it away.
11429 (define_peephole2
11430   [(match_scratch:SI 3 "r")
11431    (parallel [(set (match_operand:DI 0 "register_operand" "")
11432                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11433                                 (match_operand:QI 2 "nonmemory_operand" "")))
11434               (clobber (reg:CC FLAGS_REG))])
11435    (match_dup 3)]
11436   "!TARGET_64BIT && TARGET_CMOVE"
11437   [(const_int 0)]
11438   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11440 (define_split
11441   [(set (match_operand:DI 0 "register_operand" "")
11442         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11443                      (match_operand:QI 2 "nonmemory_operand" "")))
11444    (clobber (reg:CC FLAGS_REG))]
11445   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11446                      ? flow2_completed : reload_completed)"
11447   [(const_int 0)]
11448   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11450 (define_insn "x86_shrd_1"
11451   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11452         (ior:SI (ashiftrt:SI (match_dup 0)
11453                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11454                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11455                   (minus:QI (const_int 32) (match_dup 2)))))
11456    (clobber (reg:CC FLAGS_REG))]
11457   ""
11458   "@
11459    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11460    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11461   [(set_attr "type" "ishift")
11462    (set_attr "prefix_0f" "1")
11463    (set_attr "pent_pair" "np")
11464    (set_attr "mode" "SI")])
11466 (define_expand "x86_shift_adj_3"
11467   [(use (match_operand:SI 0 "register_operand" ""))
11468    (use (match_operand:SI 1 "register_operand" ""))
11469    (use (match_operand:QI 2 "register_operand" ""))]
11470   ""
11472   rtx label = gen_label_rtx ();
11473   rtx tmp;
11475   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11477   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11478   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11479   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11480                               gen_rtx_LABEL_REF (VOIDmode, label),
11481                               pc_rtx);
11482   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11483   JUMP_LABEL (tmp) = label;
11485   emit_move_insn (operands[0], operands[1]);
11486   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11488   emit_label (label);
11489   LABEL_NUSES (label) = 1;
11491   DONE;
11494 (define_insn "ashrsi3_31"
11495   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11496         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11497                      (match_operand:SI 2 "const_int_operand" "i,i")))
11498    (clobber (reg:CC FLAGS_REG))]
11499   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11500    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11501   "@
11502    {cltd|cdq}
11503    sar{l}\t{%2, %0|%0, %2}"
11504   [(set_attr "type" "imovx,ishift")
11505    (set_attr "prefix_0f" "0,*")
11506    (set_attr "length_immediate" "0,*")
11507    (set_attr "modrm" "0,1")
11508    (set_attr "mode" "SI")])
11510 (define_insn "*ashrsi3_31_zext"
11511   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11512         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11513                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11514    (clobber (reg:CC FLAGS_REG))]
11515   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11516    && INTVAL (operands[2]) == 31
11517    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11518   "@
11519    {cltd|cdq}
11520    sar{l}\t{%2, %k0|%k0, %2}"
11521   [(set_attr "type" "imovx,ishift")
11522    (set_attr "prefix_0f" "0,*")
11523    (set_attr "length_immediate" "0,*")
11524    (set_attr "modrm" "0,1")
11525    (set_attr "mode" "SI")])
11527 (define_expand "ashrsi3"
11528   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11529         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11530                      (match_operand:QI 2 "nonmemory_operand" "")))
11531    (clobber (reg:CC FLAGS_REG))]
11532   ""
11533   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11535 (define_insn "*ashrsi3_1_one_bit"
11536   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11537         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11538                      (match_operand:QI 2 "const1_operand" "")))
11539    (clobber (reg:CC FLAGS_REG))]
11540   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11541    && (TARGET_SHIFT1 || optimize_size)"
11542   "sar{l}\t%0"
11543   [(set_attr "type" "ishift")
11544    (set (attr "length") 
11545      (if_then_else (match_operand:SI 0 "register_operand" "") 
11546         (const_string "2")
11547         (const_string "*")))])
11549 (define_insn "*ashrsi3_1_one_bit_zext"
11550   [(set (match_operand:DI 0 "register_operand" "=r")
11551         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11552                                      (match_operand:QI 2 "const1_operand" ""))))
11553    (clobber (reg:CC FLAGS_REG))]
11554   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11555    && (TARGET_SHIFT1 || optimize_size)"
11556   "sar{l}\t%k0"
11557   [(set_attr "type" "ishift")
11558    (set_attr "length" "2")])
11560 (define_insn "*ashrsi3_1"
11561   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11562         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11563                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11564    (clobber (reg:CC FLAGS_REG))]
11565   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11566   "@
11567    sar{l}\t{%2, %0|%0, %2}
11568    sar{l}\t{%b2, %0|%0, %b2}"
11569   [(set_attr "type" "ishift")
11570    (set_attr "mode" "SI")])
11572 (define_insn "*ashrsi3_1_zext"
11573   [(set (match_operand:DI 0 "register_operand" "=r,r")
11574         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11575                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11576    (clobber (reg:CC FLAGS_REG))]
11577   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11578   "@
11579    sar{l}\t{%2, %k0|%k0, %2}
11580    sar{l}\t{%b2, %k0|%k0, %b2}"
11581   [(set_attr "type" "ishift")
11582    (set_attr "mode" "SI")])
11584 ;; This pattern can't accept a variable shift count, since shifts by
11585 ;; zero don't affect the flags.  We assume that shifts by constant
11586 ;; zero are optimized away.
11587 (define_insn "*ashrsi3_one_bit_cmp"
11588   [(set (reg FLAGS_REG)
11589         (compare
11590           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11591                        (match_operand:QI 2 "const1_operand" ""))
11592           (const_int 0)))
11593    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11594         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11595   "ix86_match_ccmode (insn, CCGOCmode)
11596    && (TARGET_SHIFT1 || optimize_size)
11597    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11598   "sar{l}\t%0"
11599   [(set_attr "type" "ishift")
11600    (set (attr "length") 
11601      (if_then_else (match_operand:SI 0 "register_operand" "") 
11602         (const_string "2")
11603         (const_string "*")))])
11605 (define_insn "*ashrsi3_one_bit_cconly"
11606   [(set (reg FLAGS_REG)
11607         (compare
11608           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11609                        (match_operand:QI 2 "const1_operand" ""))
11610           (const_int 0)))
11611    (clobber (match_scratch:SI 0 "=r"))]
11612   "ix86_match_ccmode (insn, CCGOCmode)
11613    && (TARGET_SHIFT1 || optimize_size)
11614    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11615   "sar{l}\t%0"
11616   [(set_attr "type" "ishift")
11617    (set_attr "length" "2")])
11619 (define_insn "*ashrsi3_one_bit_cmp_zext"
11620   [(set (reg FLAGS_REG)
11621         (compare
11622           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11623                        (match_operand:QI 2 "const1_operand" ""))
11624           (const_int 0)))
11625    (set (match_operand:DI 0 "register_operand" "=r")
11626         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11627   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11628    && (TARGET_SHIFT1 || optimize_size)
11629    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11630   "sar{l}\t%k0"
11631   [(set_attr "type" "ishift")
11632    (set_attr "length" "2")])
11634 ;; This pattern can't accept a variable shift count, since shifts by
11635 ;; zero don't affect the flags.  We assume that shifts by constant
11636 ;; zero are optimized away.
11637 (define_insn "*ashrsi3_cmp"
11638   [(set (reg FLAGS_REG)
11639         (compare
11640           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11641                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11642           (const_int 0)))
11643    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11644         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11645   "ix86_match_ccmode (insn, CCGOCmode)
11646    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11647    && (optimize_size
11648        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11649   "sar{l}\t{%2, %0|%0, %2}"
11650   [(set_attr "type" "ishift")
11651    (set_attr "mode" "SI")])
11653 (define_insn "*ashrsi3_cconly"
11654   [(set (reg FLAGS_REG)
11655         (compare
11656           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11657                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11658           (const_int 0)))
11659    (clobber (match_scratch:SI 0 "=r"))]
11660   "ix86_match_ccmode (insn, CCGOCmode)
11661    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11662    && (optimize_size
11663        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11664   "sar{l}\t{%2, %0|%0, %2}"
11665   [(set_attr "type" "ishift")
11666    (set_attr "mode" "SI")])
11668 (define_insn "*ashrsi3_cmp_zext"
11669   [(set (reg FLAGS_REG)
11670         (compare
11671           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11672                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11673           (const_int 0)))
11674    (set (match_operand:DI 0 "register_operand" "=r")
11675         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11676   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11677    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11678    && (optimize_size
11679        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11680   "sar{l}\t{%2, %k0|%k0, %2}"
11681   [(set_attr "type" "ishift")
11682    (set_attr "mode" "SI")])
11684 (define_expand "ashrhi3"
11685   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11686         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11687                      (match_operand:QI 2 "nonmemory_operand" "")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "TARGET_HIMODE_MATH"
11690   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11692 (define_insn "*ashrhi3_1_one_bit"
11693   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11694         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11695                      (match_operand:QI 2 "const1_operand" "")))
11696    (clobber (reg:CC FLAGS_REG))]
11697   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11698    && (TARGET_SHIFT1 || optimize_size)"
11699   "sar{w}\t%0"
11700   [(set_attr "type" "ishift")
11701    (set (attr "length") 
11702      (if_then_else (match_operand 0 "register_operand" "") 
11703         (const_string "2")
11704         (const_string "*")))])
11706 (define_insn "*ashrhi3_1"
11707   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11708         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11709                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11710    (clobber (reg:CC FLAGS_REG))]
11711   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11712   "@
11713    sar{w}\t{%2, %0|%0, %2}
11714    sar{w}\t{%b2, %0|%0, %b2}"
11715   [(set_attr "type" "ishift")
11716    (set_attr "mode" "HI")])
11718 ;; This pattern can't accept a variable shift count, since shifts by
11719 ;; zero don't affect the flags.  We assume that shifts by constant
11720 ;; zero are optimized away.
11721 (define_insn "*ashrhi3_one_bit_cmp"
11722   [(set (reg FLAGS_REG)
11723         (compare
11724           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11725                        (match_operand:QI 2 "const1_operand" ""))
11726           (const_int 0)))
11727    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11728         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11729   "ix86_match_ccmode (insn, CCGOCmode)
11730    && (TARGET_SHIFT1 || optimize_size)
11731    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11732   "sar{w}\t%0"
11733   [(set_attr "type" "ishift")
11734    (set (attr "length") 
11735      (if_then_else (match_operand 0 "register_operand" "") 
11736         (const_string "2")
11737         (const_string "*")))])
11739 (define_insn "*ashrhi3_one_bit_cconly"
11740   [(set (reg FLAGS_REG)
11741         (compare
11742           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11743                        (match_operand:QI 2 "const1_operand" ""))
11744           (const_int 0)))
11745    (clobber (match_scratch:HI 0 "=r"))]
11746   "ix86_match_ccmode (insn, CCGOCmode)
11747    && (TARGET_SHIFT1 || optimize_size)
11748    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11749   "sar{w}\t%0"
11750   [(set_attr "type" "ishift")
11751    (set_attr "length" "2")])
11753 ;; This pattern can't accept a variable shift count, since shifts by
11754 ;; zero don't affect the flags.  We assume that shifts by constant
11755 ;; zero are optimized away.
11756 (define_insn "*ashrhi3_cmp"
11757   [(set (reg FLAGS_REG)
11758         (compare
11759           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11760                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11761           (const_int 0)))
11762    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11763         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11764   "ix86_match_ccmode (insn, CCGOCmode)
11765    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11766    && (optimize_size
11767        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11768   "sar{w}\t{%2, %0|%0, %2}"
11769   [(set_attr "type" "ishift")
11770    (set_attr "mode" "HI")])
11772 (define_insn "*ashrhi3_cconly"
11773   [(set (reg FLAGS_REG)
11774         (compare
11775           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11776                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11777           (const_int 0)))
11778    (clobber (match_scratch:HI 0 "=r"))]
11779   "ix86_match_ccmode (insn, CCGOCmode)
11780    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11781    && (optimize_size
11782        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11783   "sar{w}\t{%2, %0|%0, %2}"
11784   [(set_attr "type" "ishift")
11785    (set_attr "mode" "HI")])
11787 (define_expand "ashrqi3"
11788   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11789         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11790                      (match_operand:QI 2 "nonmemory_operand" "")))
11791    (clobber (reg:CC FLAGS_REG))]
11792   "TARGET_QIMODE_MATH"
11793   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11795 (define_insn "*ashrqi3_1_one_bit"
11796   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11797         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11798                      (match_operand:QI 2 "const1_operand" "")))
11799    (clobber (reg:CC FLAGS_REG))]
11800   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11801    && (TARGET_SHIFT1 || optimize_size)"
11802   "sar{b}\t%0"
11803   [(set_attr "type" "ishift")
11804    (set (attr "length") 
11805      (if_then_else (match_operand 0 "register_operand" "") 
11806         (const_string "2")
11807         (const_string "*")))])
11809 (define_insn "*ashrqi3_1_one_bit_slp"
11810   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11811         (ashiftrt:QI (match_dup 0)
11812                      (match_operand:QI 1 "const1_operand" "")))
11813    (clobber (reg:CC FLAGS_REG))]
11814   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11815    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11816    && (TARGET_SHIFT1 || optimize_size)"
11817   "sar{b}\t%0"
11818   [(set_attr "type" "ishift1")
11819    (set (attr "length") 
11820      (if_then_else (match_operand 0 "register_operand" "") 
11821         (const_string "2")
11822         (const_string "*")))])
11824 (define_insn "*ashrqi3_1"
11825   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11826         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11827                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11828    (clobber (reg:CC FLAGS_REG))]
11829   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11830   "@
11831    sar{b}\t{%2, %0|%0, %2}
11832    sar{b}\t{%b2, %0|%0, %b2}"
11833   [(set_attr "type" "ishift")
11834    (set_attr "mode" "QI")])
11836 (define_insn "*ashrqi3_1_slp"
11837   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11838         (ashiftrt: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    sar{b}\t{%1, %0|%0, %1}
11845    sar{b}\t{%b1, %0|%0, %b1}"
11846   [(set_attr "type" "ishift1")
11847    (set_attr "mode" "QI")])
11849 ;; This pattern can't accept a variable shift count, since shifts by
11850 ;; zero don't affect the flags.  We assume that shifts by constant
11851 ;; zero are optimized away.
11852 (define_insn "*ashrqi3_one_bit_cmp"
11853   [(set (reg FLAGS_REG)
11854         (compare
11855           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11856                        (match_operand:QI 2 "const1_operand" "I"))
11857           (const_int 0)))
11858    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11859         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11860   "ix86_match_ccmode (insn, CCGOCmode)
11861    && (TARGET_SHIFT1 || optimize_size)
11862    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11863   "sar{b}\t%0"
11864   [(set_attr "type" "ishift")
11865    (set (attr "length") 
11866      (if_then_else (match_operand 0 "register_operand" "") 
11867         (const_string "2")
11868         (const_string "*")))])
11870 (define_insn "*ashrqi3_one_bit_cconly"
11871   [(set (reg FLAGS_REG)
11872         (compare
11873           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11874                        (match_operand:QI 2 "const1_operand" "I"))
11875           (const_int 0)))
11876    (clobber (match_scratch:QI 0 "=q"))]
11877   "ix86_match_ccmode (insn, CCGOCmode)
11878    && (TARGET_SHIFT1 || optimize_size)
11879    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11880   "sar{b}\t%0"
11881   [(set_attr "type" "ishift")
11882    (set_attr "length" "2")])
11884 ;; This pattern can't accept a variable shift count, since shifts by
11885 ;; zero don't affect the flags.  We assume that shifts by constant
11886 ;; zero are optimized away.
11887 (define_insn "*ashrqi3_cmp"
11888   [(set (reg FLAGS_REG)
11889         (compare
11890           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11891                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11892           (const_int 0)))
11893    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11894         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11895   "ix86_match_ccmode (insn, CCGOCmode)
11896    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11897    && (optimize_size
11898        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11899   "sar{b}\t{%2, %0|%0, %2}"
11900   [(set_attr "type" "ishift")
11901    (set_attr "mode" "QI")])
11903 (define_insn "*ashrqi3_cconly"
11904   [(set (reg FLAGS_REG)
11905         (compare
11906           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11907                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11908           (const_int 0)))
11909    (clobber (match_scratch:QI 0 "=q"))]
11910   "ix86_match_ccmode (insn, CCGOCmode)
11911    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11912    && (optimize_size
11913        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11914   "sar{b}\t{%2, %0|%0, %2}"
11915   [(set_attr "type" "ishift")
11916    (set_attr "mode" "QI")])
11919 ;; Logical shift instructions
11921 ;; See comment above `ashldi3' about how this works.
11923 (define_expand "lshrti3"
11924   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11925                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11926                                 (match_operand:QI 2 "nonmemory_operand" "")))
11927               (clobber (reg:CC FLAGS_REG))])]
11928   "TARGET_64BIT"
11930   if (! immediate_operand (operands[2], QImode))
11931     {
11932       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11933       DONE;
11934     }
11935   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11936   DONE;
11939 (define_insn "lshrti3_1"
11940   [(set (match_operand:TI 0 "register_operand" "=r")
11941         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11942                      (match_operand:QI 2 "register_operand" "c")))
11943    (clobber (match_scratch:DI 3 "=&r"))
11944    (clobber (reg:CC FLAGS_REG))]
11945   "TARGET_64BIT"
11946   "#"
11947   [(set_attr "type" "multi")])
11949 (define_insn "*lshrti3_2"
11950   [(set (match_operand:TI 0 "register_operand" "=r")
11951         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11952                      (match_operand:QI 2 "immediate_operand" "O")))
11953    (clobber (reg:CC FLAGS_REG))]
11954   "TARGET_64BIT"
11955   "#"
11956   [(set_attr "type" "multi")])
11958 (define_split 
11959   [(set (match_operand:TI 0 "register_operand" "")
11960         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11961                      (match_operand:QI 2 "register_operand" "")))
11962    (clobber (match_scratch:DI 3 ""))
11963    (clobber (reg:CC FLAGS_REG))]
11964   "TARGET_64BIT && reload_completed"
11965   [(const_int 0)]
11966   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11968 (define_split 
11969   [(set (match_operand:TI 0 "register_operand" "")
11970         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11971                      (match_operand:QI 2 "immediate_operand" "")))
11972    (clobber (reg:CC FLAGS_REG))]
11973   "TARGET_64BIT && reload_completed"
11974   [(const_int 0)]
11975   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11977 (define_expand "lshrdi3"
11978   [(set (match_operand:DI 0 "shiftdi_operand" "")
11979         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11980                      (match_operand:QI 2 "nonmemory_operand" "")))]
11981   ""
11982   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11984 (define_insn "*lshrdi3_1_one_bit_rex64"
11985   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11986         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11987                      (match_operand:QI 2 "const1_operand" "")))
11988    (clobber (reg:CC FLAGS_REG))]
11989   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11990    && (TARGET_SHIFT1 || optimize_size)"
11991   "shr{q}\t%0"
11992   [(set_attr "type" "ishift")
11993    (set (attr "length") 
11994      (if_then_else (match_operand:DI 0 "register_operand" "") 
11995         (const_string "2")
11996         (const_string "*")))])
11998 (define_insn "*lshrdi3_1_rex64"
11999   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12000         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12001                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12002    (clobber (reg:CC FLAGS_REG))]
12003   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12004   "@
12005    shr{q}\t{%2, %0|%0, %2}
12006    shr{q}\t{%b2, %0|%0, %b2}"
12007   [(set_attr "type" "ishift")
12008    (set_attr "mode" "DI")])
12010 ;; This pattern can't accept a variable shift count, since shifts by
12011 ;; zero don't affect the flags.  We assume that shifts by constant
12012 ;; zero are optimized away.
12013 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12014   [(set (reg FLAGS_REG)
12015         (compare
12016           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12017                        (match_operand:QI 2 "const1_operand" ""))
12018           (const_int 0)))
12019    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12020         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12021   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12022    && (TARGET_SHIFT1 || optimize_size)
12023    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12024   "shr{q}\t%0"
12025   [(set_attr "type" "ishift")
12026    (set (attr "length") 
12027      (if_then_else (match_operand:DI 0 "register_operand" "") 
12028         (const_string "2")
12029         (const_string "*")))])
12031 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12032   [(set (reg FLAGS_REG)
12033         (compare
12034           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12035                        (match_operand:QI 2 "const1_operand" ""))
12036           (const_int 0)))
12037    (clobber (match_scratch:DI 0 "=r"))]
12038   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12039    && (TARGET_SHIFT1 || optimize_size)
12040    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12041   "shr{q}\t%0"
12042   [(set_attr "type" "ishift")
12043    (set_attr "length" "2")])
12045 ;; This pattern can't accept a variable shift count, since shifts by
12046 ;; zero don't affect the flags.  We assume that shifts by constant
12047 ;; zero are optimized away.
12048 (define_insn "*lshrdi3_cmp_rex64"
12049   [(set (reg FLAGS_REG)
12050         (compare
12051           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12052                        (match_operand:QI 2 "const_int_operand" "e"))
12053           (const_int 0)))
12054    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12055         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12056   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12057    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12058    && (optimize_size
12059        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12060   "shr{q}\t{%2, %0|%0, %2}"
12061   [(set_attr "type" "ishift")
12062    (set_attr "mode" "DI")])
12064 (define_insn "*lshrdi3_cconly_rex64"
12065   [(set (reg FLAGS_REG)
12066         (compare
12067           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12068                        (match_operand:QI 2 "const_int_operand" "e"))
12069           (const_int 0)))
12070    (clobber (match_scratch:DI 0 "=r"))]
12071   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12072    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12073    && (optimize_size
12074        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12075   "shr{q}\t{%2, %0|%0, %2}"
12076   [(set_attr "type" "ishift")
12077    (set_attr "mode" "DI")])
12079 (define_insn "*lshrdi3_1"
12080   [(set (match_operand:DI 0 "register_operand" "=r")
12081         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12082                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "!TARGET_64BIT"
12085   "#"
12086   [(set_attr "type" "multi")])
12088 ;; By default we don't ask for a scratch register, because when DImode
12089 ;; values are manipulated, registers are already at a premium.  But if
12090 ;; we have one handy, we won't turn it away.
12091 (define_peephole2
12092   [(match_scratch:SI 3 "r")
12093    (parallel [(set (match_operand:DI 0 "register_operand" "")
12094                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12095                                 (match_operand:QI 2 "nonmemory_operand" "")))
12096               (clobber (reg:CC FLAGS_REG))])
12097    (match_dup 3)]
12098   "!TARGET_64BIT && TARGET_CMOVE"
12099   [(const_int 0)]
12100   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12102 (define_split 
12103   [(set (match_operand:DI 0 "register_operand" "")
12104         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12105                      (match_operand:QI 2 "nonmemory_operand" "")))
12106    (clobber (reg:CC FLAGS_REG))]
12107   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12108                      ? flow2_completed : reload_completed)"
12109   [(const_int 0)]
12110   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12112 (define_expand "lshrsi3"
12113   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12114         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12115                      (match_operand:QI 2 "nonmemory_operand" "")))
12116    (clobber (reg:CC FLAGS_REG))]
12117   ""
12118   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12120 (define_insn "*lshrsi3_1_one_bit"
12121   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12122         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12123                      (match_operand:QI 2 "const1_operand" "")))
12124    (clobber (reg:CC FLAGS_REG))]
12125   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12126    && (TARGET_SHIFT1 || optimize_size)"
12127   "shr{l}\t%0"
12128   [(set_attr "type" "ishift")
12129    (set (attr "length") 
12130      (if_then_else (match_operand:SI 0 "register_operand" "") 
12131         (const_string "2")
12132         (const_string "*")))])
12134 (define_insn "*lshrsi3_1_one_bit_zext"
12135   [(set (match_operand:DI 0 "register_operand" "=r")
12136         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12137                      (match_operand:QI 2 "const1_operand" "")))
12138    (clobber (reg:CC FLAGS_REG))]
12139   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12140    && (TARGET_SHIFT1 || optimize_size)"
12141   "shr{l}\t%k0"
12142   [(set_attr "type" "ishift")
12143    (set_attr "length" "2")])
12145 (define_insn "*lshrsi3_1"
12146   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12147         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12148                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12149    (clobber (reg:CC FLAGS_REG))]
12150   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12151   "@
12152    shr{l}\t{%2, %0|%0, %2}
12153    shr{l}\t{%b2, %0|%0, %b2}"
12154   [(set_attr "type" "ishift")
12155    (set_attr "mode" "SI")])
12157 (define_insn "*lshrsi3_1_zext"
12158   [(set (match_operand:DI 0 "register_operand" "=r,r")
12159         (zero_extend:DI
12160           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12161                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12164   "@
12165    shr{l}\t{%2, %k0|%k0, %2}
12166    shr{l}\t{%b2, %k0|%k0, %b2}"
12167   [(set_attr "type" "ishift")
12168    (set_attr "mode" "SI")])
12170 ;; This pattern can't accept a variable shift count, since shifts by
12171 ;; zero don't affect the flags.  We assume that shifts by constant
12172 ;; zero are optimized away.
12173 (define_insn "*lshrsi3_one_bit_cmp"
12174   [(set (reg FLAGS_REG)
12175         (compare
12176           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12177                        (match_operand:QI 2 "const1_operand" ""))
12178           (const_int 0)))
12179    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12180         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12181   "ix86_match_ccmode (insn, CCGOCmode)
12182    && (TARGET_SHIFT1 || optimize_size)
12183    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12184   "shr{l}\t%0"
12185   [(set_attr "type" "ishift")
12186    (set (attr "length") 
12187      (if_then_else (match_operand:SI 0 "register_operand" "") 
12188         (const_string "2")
12189         (const_string "*")))])
12191 (define_insn "*lshrsi3_one_bit_cconly"
12192   [(set (reg FLAGS_REG)
12193         (compare
12194           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12195                        (match_operand:QI 2 "const1_operand" ""))
12196           (const_int 0)))
12197    (clobber (match_scratch:SI 0 "=r"))]
12198   "ix86_match_ccmode (insn, CCGOCmode)
12199    && (TARGET_SHIFT1 || optimize_size)
12200    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12201   "shr{l}\t%0"
12202   [(set_attr "type" "ishift")
12203    (set_attr "length" "2")])
12205 (define_insn "*lshrsi3_cmp_one_bit_zext"
12206   [(set (reg FLAGS_REG)
12207         (compare
12208           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12209                        (match_operand:QI 2 "const1_operand" ""))
12210           (const_int 0)))
12211    (set (match_operand:DI 0 "register_operand" "=r")
12212         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12213   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12214    && (TARGET_SHIFT1 || optimize_size)
12215    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12216   "shr{l}\t%k0"
12217   [(set_attr "type" "ishift")
12218    (set_attr "length" "2")])
12220 ;; This pattern can't accept a variable shift count, since shifts by
12221 ;; zero don't affect the flags.  We assume that shifts by constant
12222 ;; zero are optimized away.
12223 (define_insn "*lshrsi3_cmp"
12224   [(set (reg FLAGS_REG)
12225         (compare
12226           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12227                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12228           (const_int 0)))
12229    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12230         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12231   "ix86_match_ccmode (insn, CCGOCmode)
12232    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12233    && (optimize_size
12234        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12235   "shr{l}\t{%2, %0|%0, %2}"
12236   [(set_attr "type" "ishift")
12237    (set_attr "mode" "SI")])
12239 (define_insn "*lshrsi3_cconly"
12240   [(set (reg FLAGS_REG)
12241       (compare
12242         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12243                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12244         (const_int 0)))
12245    (clobber (match_scratch:SI 0 "=r"))]
12246   "ix86_match_ccmode (insn, CCGOCmode)
12247    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12248    && (optimize_size
12249        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12250   "shr{l}\t{%2, %0|%0, %2}"
12251   [(set_attr "type" "ishift")
12252    (set_attr "mode" "SI")])
12254 (define_insn "*lshrsi3_cmp_zext"
12255   [(set (reg FLAGS_REG)
12256         (compare
12257           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12258                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12259           (const_int 0)))
12260    (set (match_operand:DI 0 "register_operand" "=r")
12261         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12262   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12263    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12264    && (optimize_size
12265        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12266   "shr{l}\t{%2, %k0|%k0, %2}"
12267   [(set_attr "type" "ishift")
12268    (set_attr "mode" "SI")])
12270 (define_expand "lshrhi3"
12271   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12272         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12273                      (match_operand:QI 2 "nonmemory_operand" "")))
12274    (clobber (reg:CC FLAGS_REG))]
12275   "TARGET_HIMODE_MATH"
12276   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12278 (define_insn "*lshrhi3_1_one_bit"
12279   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12280         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12281                      (match_operand:QI 2 "const1_operand" "")))
12282    (clobber (reg:CC FLAGS_REG))]
12283   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12284    && (TARGET_SHIFT1 || optimize_size)"
12285   "shr{w}\t%0"
12286   [(set_attr "type" "ishift")
12287    (set (attr "length") 
12288      (if_then_else (match_operand 0 "register_operand" "") 
12289         (const_string "2")
12290         (const_string "*")))])
12292 (define_insn "*lshrhi3_1"
12293   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12294         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12295                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12296    (clobber (reg:CC FLAGS_REG))]
12297   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12298   "@
12299    shr{w}\t{%2, %0|%0, %2}
12300    shr{w}\t{%b2, %0|%0, %b2}"
12301   [(set_attr "type" "ishift")
12302    (set_attr "mode" "HI")])
12304 ;; This pattern can't accept a variable shift count, since shifts by
12305 ;; zero don't affect the flags.  We assume that shifts by constant
12306 ;; zero are optimized away.
12307 (define_insn "*lshrhi3_one_bit_cmp"
12308   [(set (reg FLAGS_REG)
12309         (compare
12310           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12311                        (match_operand:QI 2 "const1_operand" ""))
12312           (const_int 0)))
12313    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12314         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12315   "ix86_match_ccmode (insn, CCGOCmode)
12316    && (TARGET_SHIFT1 || optimize_size)
12317    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12318   "shr{w}\t%0"
12319   [(set_attr "type" "ishift")
12320    (set (attr "length") 
12321      (if_then_else (match_operand:SI 0 "register_operand" "") 
12322         (const_string "2")
12323         (const_string "*")))])
12325 (define_insn "*lshrhi3_one_bit_cconly"
12326   [(set (reg FLAGS_REG)
12327         (compare
12328           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12329                        (match_operand:QI 2 "const1_operand" ""))
12330           (const_int 0)))
12331    (clobber (match_scratch:HI 0 "=r"))]
12332   "ix86_match_ccmode (insn, CCGOCmode)
12333    && (TARGET_SHIFT1 || optimize_size)
12334    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12335   "shr{w}\t%0"
12336   [(set_attr "type" "ishift")
12337    (set_attr "length" "2")])
12339 ;; This pattern can't accept a variable shift count, since shifts by
12340 ;; zero don't affect the flags.  We assume that shifts by constant
12341 ;; zero are optimized away.
12342 (define_insn "*lshrhi3_cmp"
12343   [(set (reg FLAGS_REG)
12344         (compare
12345           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12346                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12347           (const_int 0)))
12348    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12349         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12350   "ix86_match_ccmode (insn, CCGOCmode)
12351    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12352    && (optimize_size
12353        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12354   "shr{w}\t{%2, %0|%0, %2}"
12355   [(set_attr "type" "ishift")
12356    (set_attr "mode" "HI")])
12358 (define_insn "*lshrhi3_cconly"
12359   [(set (reg FLAGS_REG)
12360         (compare
12361           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12362                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12363           (const_int 0)))
12364    (clobber (match_scratch:HI 0 "=r"))]
12365   "ix86_match_ccmode (insn, CCGOCmode)
12366    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12367    && (optimize_size
12368        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12369   "shr{w}\t{%2, %0|%0, %2}"
12370   [(set_attr "type" "ishift")
12371    (set_attr "mode" "HI")])
12373 (define_expand "lshrqi3"
12374   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12375         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12376                      (match_operand:QI 2 "nonmemory_operand" "")))
12377    (clobber (reg:CC FLAGS_REG))]
12378   "TARGET_QIMODE_MATH"
12379   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12381 (define_insn "*lshrqi3_1_one_bit"
12382   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12383         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12384                      (match_operand:QI 2 "const1_operand" "")))
12385    (clobber (reg:CC FLAGS_REG))]
12386   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12387    && (TARGET_SHIFT1 || optimize_size)"
12388   "shr{b}\t%0"
12389   [(set_attr "type" "ishift")
12390    (set (attr "length") 
12391      (if_then_else (match_operand 0 "register_operand" "") 
12392         (const_string "2")
12393         (const_string "*")))])
12395 (define_insn "*lshrqi3_1_one_bit_slp"
12396   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12397         (lshiftrt:QI (match_dup 0)
12398                      (match_operand:QI 1 "const1_operand" "")))
12399    (clobber (reg:CC FLAGS_REG))]
12400   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12401    && (TARGET_SHIFT1 || optimize_size)"
12402   "shr{b}\t%0"
12403   [(set_attr "type" "ishift1")
12404    (set (attr "length") 
12405      (if_then_else (match_operand 0 "register_operand" "") 
12406         (const_string "2")
12407         (const_string "*")))])
12409 (define_insn "*lshrqi3_1"
12410   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12411         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12412                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12413    (clobber (reg:CC FLAGS_REG))]
12414   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12415   "@
12416    shr{b}\t{%2, %0|%0, %2}
12417    shr{b}\t{%b2, %0|%0, %b2}"
12418   [(set_attr "type" "ishift")
12419    (set_attr "mode" "QI")])
12421 (define_insn "*lshrqi3_1_slp"
12422   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12423         (lshiftrt:QI (match_dup 0)
12424                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12425    (clobber (reg:CC FLAGS_REG))]
12426   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12427    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12428   "@
12429    shr{b}\t{%1, %0|%0, %1}
12430    shr{b}\t{%b1, %0|%0, %b1}"
12431   [(set_attr "type" "ishift1")
12432    (set_attr "mode" "QI")])
12434 ;; This pattern can't accept a variable shift count, since shifts by
12435 ;; zero don't affect the flags.  We assume that shifts by constant
12436 ;; zero are optimized away.
12437 (define_insn "*lshrqi2_one_bit_cmp"
12438   [(set (reg FLAGS_REG)
12439         (compare
12440           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12441                        (match_operand:QI 2 "const1_operand" ""))
12442           (const_int 0)))
12443    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12444         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12445   "ix86_match_ccmode (insn, CCGOCmode)
12446    && (TARGET_SHIFT1 || optimize_size)
12447    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12448   "shr{b}\t%0"
12449   [(set_attr "type" "ishift")
12450    (set (attr "length") 
12451      (if_then_else (match_operand:SI 0 "register_operand" "") 
12452         (const_string "2")
12453         (const_string "*")))])
12455 (define_insn "*lshrqi2_one_bit_cconly"
12456   [(set (reg FLAGS_REG)
12457         (compare
12458           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12459                        (match_operand:QI 2 "const1_operand" ""))
12460           (const_int 0)))
12461    (clobber (match_scratch:QI 0 "=q"))]
12462   "ix86_match_ccmode (insn, CCGOCmode)
12463    && (TARGET_SHIFT1 || optimize_size)
12464    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12465   "shr{b}\t%0"
12466   [(set_attr "type" "ishift")
12467    (set_attr "length" "2")])
12469 ;; This pattern can't accept a variable shift count, since shifts by
12470 ;; zero don't affect the flags.  We assume that shifts by constant
12471 ;; zero are optimized away.
12472 (define_insn "*lshrqi2_cmp"
12473   [(set (reg FLAGS_REG)
12474         (compare
12475           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12476                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12477           (const_int 0)))
12478    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12479         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12480   "ix86_match_ccmode (insn, CCGOCmode)
12481    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12482    && (optimize_size
12483        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12484   "shr{b}\t{%2, %0|%0, %2}"
12485   [(set_attr "type" "ishift")
12486    (set_attr "mode" "QI")])
12488 (define_insn "*lshrqi2_cconly"
12489   [(set (reg FLAGS_REG)
12490         (compare
12491           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12492                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12493           (const_int 0)))
12494    (clobber (match_scratch:QI 0 "=q"))]
12495   "ix86_match_ccmode (insn, CCGOCmode)
12496    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12497    && (optimize_size
12498        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12499   "shr{b}\t{%2, %0|%0, %2}"
12500   [(set_attr "type" "ishift")
12501    (set_attr "mode" "QI")])
12503 ;; Rotate instructions
12505 (define_expand "rotldi3"
12506   [(set (match_operand:DI 0 "shiftdi_operand" "")
12507         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12508                    (match_operand:QI 2 "nonmemory_operand" "")))
12509    (clobber (reg:CC FLAGS_REG))]
12510  ""
12512   if (TARGET_64BIT)
12513     {
12514       ix86_expand_binary_operator (ROTATE, DImode, operands);
12515       DONE;
12516     }
12517   if (!const_1_to_31_operand (operands[2], VOIDmode))
12518     FAIL;
12519   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12520   DONE;
12523 ;; Implement rotation using two double-precision shift instructions
12524 ;; and a scratch register.   
12525 (define_insn_and_split "ix86_rotldi3"
12526  [(set (match_operand:DI 0 "register_operand" "=r")
12527        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12528                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12529   (clobber (reg:CC FLAGS_REG))
12530   (clobber (match_scratch:SI 3 "=&r"))]
12531  "!TARGET_64BIT"
12532  "" 
12533  "&& reload_completed"
12534  [(set (match_dup 3) (match_dup 4))
12535   (parallel
12536    [(set (match_dup 4)
12537          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12538                  (lshiftrt:SI (match_dup 5)
12539                               (minus:QI (const_int 32) (match_dup 2)))))
12540     (clobber (reg:CC FLAGS_REG))])
12541   (parallel
12542    [(set (match_dup 5)
12543          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12544                  (lshiftrt:SI (match_dup 3)
12545                               (minus:QI (const_int 32) (match_dup 2)))))
12546     (clobber (reg:CC FLAGS_REG))])]
12547  "split_di (operands, 1, operands + 4, operands + 5);")
12549 (define_insn "*rotlsi3_1_one_bit_rex64"
12550   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12551         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12552                    (match_operand:QI 2 "const1_operand" "")))
12553    (clobber (reg:CC FLAGS_REG))]
12554   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12555    && (TARGET_SHIFT1 || optimize_size)"
12556   "rol{q}\t%0"
12557   [(set_attr "type" "rotate")
12558    (set (attr "length") 
12559      (if_then_else (match_operand:DI 0 "register_operand" "") 
12560         (const_string "2")
12561         (const_string "*")))])
12563 (define_insn "*rotldi3_1_rex64"
12564   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12565         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12566                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12567    (clobber (reg:CC FLAGS_REG))]
12568   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12569   "@
12570    rol{q}\t{%2, %0|%0, %2}
12571    rol{q}\t{%b2, %0|%0, %b2}"
12572   [(set_attr "type" "rotate")
12573    (set_attr "mode" "DI")])
12575 (define_expand "rotlsi3"
12576   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12577         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12578                    (match_operand:QI 2 "nonmemory_operand" "")))
12579    (clobber (reg:CC FLAGS_REG))]
12580   ""
12581   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12583 (define_insn "*rotlsi3_1_one_bit"
12584   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12585         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12586                    (match_operand:QI 2 "const1_operand" "")))
12587    (clobber (reg:CC FLAGS_REG))]
12588   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12589    && (TARGET_SHIFT1 || optimize_size)"
12590   "rol{l}\t%0"
12591   [(set_attr "type" "rotate")
12592    (set (attr "length") 
12593      (if_then_else (match_operand:SI 0 "register_operand" "") 
12594         (const_string "2")
12595         (const_string "*")))])
12597 (define_insn "*rotlsi3_1_one_bit_zext"
12598   [(set (match_operand:DI 0 "register_operand" "=r")
12599         (zero_extend:DI
12600           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12601                      (match_operand:QI 2 "const1_operand" ""))))
12602    (clobber (reg:CC FLAGS_REG))]
12603   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12604    && (TARGET_SHIFT1 || optimize_size)"
12605   "rol{l}\t%k0"
12606   [(set_attr "type" "rotate")
12607    (set_attr "length" "2")])
12609 (define_insn "*rotlsi3_1"
12610   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12611         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12612                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12613    (clobber (reg:CC FLAGS_REG))]
12614   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12615   "@
12616    rol{l}\t{%2, %0|%0, %2}
12617    rol{l}\t{%b2, %0|%0, %b2}"
12618   [(set_attr "type" "rotate")
12619    (set_attr "mode" "SI")])
12621 (define_insn "*rotlsi3_1_zext"
12622   [(set (match_operand:DI 0 "register_operand" "=r,r")
12623         (zero_extend:DI
12624           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12625                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12626    (clobber (reg:CC FLAGS_REG))]
12627   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12628   "@
12629    rol{l}\t{%2, %k0|%k0, %2}
12630    rol{l}\t{%b2, %k0|%k0, %b2}"
12631   [(set_attr "type" "rotate")
12632    (set_attr "mode" "SI")])
12634 (define_expand "rotlhi3"
12635   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12636         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12637                    (match_operand:QI 2 "nonmemory_operand" "")))
12638    (clobber (reg:CC FLAGS_REG))]
12639   "TARGET_HIMODE_MATH"
12640   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12642 (define_insn "*rotlhi3_1_one_bit"
12643   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12644         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12645                    (match_operand:QI 2 "const1_operand" "")))
12646    (clobber (reg:CC FLAGS_REG))]
12647   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12648    && (TARGET_SHIFT1 || optimize_size)"
12649   "rol{w}\t%0"
12650   [(set_attr "type" "rotate")
12651    (set (attr "length") 
12652      (if_then_else (match_operand 0 "register_operand" "") 
12653         (const_string "2")
12654         (const_string "*")))])
12656 (define_insn "*rotlhi3_1"
12657   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12658         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12659                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12660    (clobber (reg:CC FLAGS_REG))]
12661   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12662   "@
12663    rol{w}\t{%2, %0|%0, %2}
12664    rol{w}\t{%b2, %0|%0, %b2}"
12665   [(set_attr "type" "rotate")
12666    (set_attr "mode" "HI")])
12668 (define_expand "rotlqi3"
12669   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12670         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12671                    (match_operand:QI 2 "nonmemory_operand" "")))
12672    (clobber (reg:CC FLAGS_REG))]
12673   "TARGET_QIMODE_MATH"
12674   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12676 (define_insn "*rotlqi3_1_one_bit_slp"
12677   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12678         (rotate:QI (match_dup 0)
12679                    (match_operand:QI 1 "const1_operand" "")))
12680    (clobber (reg:CC FLAGS_REG))]
12681   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12682    && (TARGET_SHIFT1 || optimize_size)"
12683   "rol{b}\t%0"
12684   [(set_attr "type" "rotate1")
12685    (set (attr "length") 
12686      (if_then_else (match_operand 0 "register_operand" "") 
12687         (const_string "2")
12688         (const_string "*")))])
12690 (define_insn "*rotlqi3_1_one_bit"
12691   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12692         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12693                    (match_operand:QI 2 "const1_operand" "")))
12694    (clobber (reg:CC FLAGS_REG))]
12695   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12696    && (TARGET_SHIFT1 || optimize_size)"
12697   "rol{b}\t%0"
12698   [(set_attr "type" "rotate")
12699    (set (attr "length") 
12700      (if_then_else (match_operand 0 "register_operand" "") 
12701         (const_string "2")
12702         (const_string "*")))])
12704 (define_insn "*rotlqi3_1_slp"
12705   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12706         (rotate:QI (match_dup 0)
12707                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12708    (clobber (reg:CC FLAGS_REG))]
12709   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12710    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12711   "@
12712    rol{b}\t{%1, %0|%0, %1}
12713    rol{b}\t{%b1, %0|%0, %b1}"
12714   [(set_attr "type" "rotate1")
12715    (set_attr "mode" "QI")])
12717 (define_insn "*rotlqi3_1"
12718   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12719         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12720                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12721    (clobber (reg:CC FLAGS_REG))]
12722   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12723   "@
12724    rol{b}\t{%2, %0|%0, %2}
12725    rol{b}\t{%b2, %0|%0, %b2}"
12726   [(set_attr "type" "rotate")
12727    (set_attr "mode" "QI")])
12729 (define_expand "rotrdi3"
12730   [(set (match_operand:DI 0 "shiftdi_operand" "")
12731         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12732                    (match_operand:QI 2 "nonmemory_operand" "")))
12733    (clobber (reg:CC FLAGS_REG))]
12734  ""
12736   if (TARGET_64BIT)
12737     {
12738       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12739       DONE;
12740     }
12741   if (!const_1_to_31_operand (operands[2], VOIDmode))
12742     FAIL;
12743   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12744   DONE;
12746   
12747 ;; Implement rotation using two double-precision shift instructions
12748 ;; and a scratch register.   
12749 (define_insn_and_split "ix86_rotrdi3"
12750  [(set (match_operand:DI 0 "register_operand" "=r")
12751        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12752                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12753   (clobber (reg:CC FLAGS_REG))
12754   (clobber (match_scratch:SI 3 "=&r"))]
12755  "!TARGET_64BIT"
12756  ""
12757  "&& reload_completed"
12758  [(set (match_dup 3) (match_dup 4))
12759   (parallel
12760    [(set (match_dup 4)
12761          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12762                  (ashift:SI (match_dup 5)
12763                             (minus:QI (const_int 32) (match_dup 2)))))
12764     (clobber (reg:CC FLAGS_REG))])
12765   (parallel
12766    [(set (match_dup 5)
12767          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12768                  (ashift:SI (match_dup 3)
12769                             (minus:QI (const_int 32) (match_dup 2)))))
12770     (clobber (reg:CC FLAGS_REG))])]
12771  "split_di (operands, 1, operands + 4, operands + 5);")
12773 (define_insn "*rotrdi3_1_one_bit_rex64"
12774   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12775         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12776                      (match_operand:QI 2 "const1_operand" "")))
12777    (clobber (reg:CC FLAGS_REG))]
12778   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12779    && (TARGET_SHIFT1 || optimize_size)"
12780   "ror{q}\t%0"
12781   [(set_attr "type" "rotate")
12782    (set (attr "length") 
12783      (if_then_else (match_operand:DI 0 "register_operand" "") 
12784         (const_string "2")
12785         (const_string "*")))])
12787 (define_insn "*rotrdi3_1_rex64"
12788   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12789         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12790                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12791    (clobber (reg:CC FLAGS_REG))]
12792   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12793   "@
12794    ror{q}\t{%2, %0|%0, %2}
12795    ror{q}\t{%b2, %0|%0, %b2}"
12796   [(set_attr "type" "rotate")
12797    (set_attr "mode" "DI")])
12799 (define_expand "rotrsi3"
12800   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12801         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12802                      (match_operand:QI 2 "nonmemory_operand" "")))
12803    (clobber (reg:CC FLAGS_REG))]
12804   ""
12805   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12807 (define_insn "*rotrsi3_1_one_bit"
12808   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12809         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12810                      (match_operand:QI 2 "const1_operand" "")))
12811    (clobber (reg:CC FLAGS_REG))]
12812   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12813    && (TARGET_SHIFT1 || optimize_size)"
12814   "ror{l}\t%0"
12815   [(set_attr "type" "rotate")
12816    (set (attr "length") 
12817      (if_then_else (match_operand:SI 0 "register_operand" "") 
12818         (const_string "2")
12819         (const_string "*")))])
12821 (define_insn "*rotrsi3_1_one_bit_zext"
12822   [(set (match_operand:DI 0 "register_operand" "=r")
12823         (zero_extend:DI
12824           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12825                        (match_operand:QI 2 "const1_operand" ""))))
12826    (clobber (reg:CC FLAGS_REG))]
12827   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12828    && (TARGET_SHIFT1 || optimize_size)"
12829   "ror{l}\t%k0"
12830   [(set_attr "type" "rotate")
12831    (set (attr "length") 
12832      (if_then_else (match_operand:SI 0 "register_operand" "") 
12833         (const_string "2")
12834         (const_string "*")))])
12836 (define_insn "*rotrsi3_1"
12837   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12838         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12839                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12840    (clobber (reg:CC FLAGS_REG))]
12841   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12842   "@
12843    ror{l}\t{%2, %0|%0, %2}
12844    ror{l}\t{%b2, %0|%0, %b2}"
12845   [(set_attr "type" "rotate")
12846    (set_attr "mode" "SI")])
12848 (define_insn "*rotrsi3_1_zext"
12849   [(set (match_operand:DI 0 "register_operand" "=r,r")
12850         (zero_extend:DI
12851           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12852                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12853    (clobber (reg:CC FLAGS_REG))]
12854   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12855   "@
12856    ror{l}\t{%2, %k0|%k0, %2}
12857    ror{l}\t{%b2, %k0|%k0, %b2}"
12858   [(set_attr "type" "rotate")
12859    (set_attr "mode" "SI")])
12861 (define_expand "rotrhi3"
12862   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12863         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12864                      (match_operand:QI 2 "nonmemory_operand" "")))
12865    (clobber (reg:CC FLAGS_REG))]
12866   "TARGET_HIMODE_MATH"
12867   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12869 (define_insn "*rotrhi3_one_bit"
12870   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12871         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12872                      (match_operand:QI 2 "const1_operand" "")))
12873    (clobber (reg:CC FLAGS_REG))]
12874   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12875    && (TARGET_SHIFT1 || optimize_size)"
12876   "ror{w}\t%0"
12877   [(set_attr "type" "rotate")
12878    (set (attr "length") 
12879      (if_then_else (match_operand 0 "register_operand" "") 
12880         (const_string "2")
12881         (const_string "*")))])
12883 (define_insn "*rotrhi3"
12884   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12885         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12886                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12887    (clobber (reg:CC FLAGS_REG))]
12888   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12889   "@
12890    ror{w}\t{%2, %0|%0, %2}
12891    ror{w}\t{%b2, %0|%0, %b2}"
12892   [(set_attr "type" "rotate")
12893    (set_attr "mode" "HI")])
12895 (define_expand "rotrqi3"
12896   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12897         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12898                      (match_operand:QI 2 "nonmemory_operand" "")))
12899    (clobber (reg:CC FLAGS_REG))]
12900   "TARGET_QIMODE_MATH"
12901   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12903 (define_insn "*rotrqi3_1_one_bit"
12904   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12905         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12906                      (match_operand:QI 2 "const1_operand" "")))
12907    (clobber (reg:CC FLAGS_REG))]
12908   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12909    && (TARGET_SHIFT1 || optimize_size)"
12910   "ror{b}\t%0"
12911   [(set_attr "type" "rotate")
12912    (set (attr "length") 
12913      (if_then_else (match_operand 0 "register_operand" "") 
12914         (const_string "2")
12915         (const_string "*")))])
12917 (define_insn "*rotrqi3_1_one_bit_slp"
12918   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12919         (rotatert:QI (match_dup 0)
12920                      (match_operand:QI 1 "const1_operand" "")))
12921    (clobber (reg:CC FLAGS_REG))]
12922   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12923    && (TARGET_SHIFT1 || optimize_size)"
12924   "ror{b}\t%0"
12925   [(set_attr "type" "rotate1")
12926    (set (attr "length") 
12927      (if_then_else (match_operand 0 "register_operand" "") 
12928         (const_string "2")
12929         (const_string "*")))])
12931 (define_insn "*rotrqi3_1"
12932   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12933         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12934                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12935    (clobber (reg:CC FLAGS_REG))]
12936   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12937   "@
12938    ror{b}\t{%2, %0|%0, %2}
12939    ror{b}\t{%b2, %0|%0, %b2}"
12940   [(set_attr "type" "rotate")
12941    (set_attr "mode" "QI")])
12943 (define_insn "*rotrqi3_1_slp"
12944   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12945         (rotatert:QI (match_dup 0)
12946                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12947    (clobber (reg:CC FLAGS_REG))]
12948   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12949    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12950   "@
12951    ror{b}\t{%1, %0|%0, %1}
12952    ror{b}\t{%b1, %0|%0, %b1}"
12953   [(set_attr "type" "rotate1")
12954    (set_attr "mode" "QI")])
12956 ;; Bit set / bit test instructions
12958 (define_expand "extv"
12959   [(set (match_operand:SI 0 "register_operand" "")
12960         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12961                          (match_operand:SI 2 "const8_operand" "")
12962                          (match_operand:SI 3 "const8_operand" "")))]
12963   ""
12965   /* Handle extractions from %ah et al.  */
12966   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12967     FAIL;
12969   /* From mips.md: extract_bit_field doesn't verify that our source
12970      matches the predicate, so check it again here.  */
12971   if (! ext_register_operand (operands[1], VOIDmode))
12972     FAIL;
12975 (define_expand "extzv"
12976   [(set (match_operand:SI 0 "register_operand" "")
12977         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12978                          (match_operand:SI 2 "const8_operand" "")
12979                          (match_operand:SI 3 "const8_operand" "")))]
12980   ""
12982   /* Handle extractions from %ah et al.  */
12983   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12984     FAIL;
12986   /* From mips.md: extract_bit_field doesn't verify that our source
12987      matches the predicate, so check it again here.  */
12988   if (! ext_register_operand (operands[1], VOIDmode))
12989     FAIL;
12992 (define_expand "insv"
12993   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12994                       (match_operand 1 "const8_operand" "")
12995                       (match_operand 2 "const8_operand" ""))
12996         (match_operand 3 "register_operand" ""))]
12997   ""
12999   /* Handle insertions to %ah et al.  */
13000   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13001     FAIL;
13003   /* From mips.md: insert_bit_field doesn't verify that our source
13004      matches the predicate, so check it again here.  */
13005   if (! ext_register_operand (operands[0], VOIDmode))
13006     FAIL;
13008   if (TARGET_64BIT)
13009     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13010   else
13011     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13013   DONE;
13016 ;; %%% bts, btr, btc, bt.
13017 ;; In general these instructions are *slow* when applied to memory,
13018 ;; since they enforce atomic operation.  When applied to registers,
13019 ;; it depends on the cpu implementation.  They're never faster than
13020 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13021 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13022 ;; within the instruction itself, so operating on bits in the high
13023 ;; 32-bits of a register becomes easier.
13025 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13026 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13027 ;; negdf respectively, so they can never be disabled entirely.
13029 (define_insn "*btsq"
13030   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13031                          (const_int 1)
13032                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13033         (const_int 1))
13034    (clobber (reg:CC FLAGS_REG))]
13035   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13036   "bts{q} %1,%0"
13037   [(set_attr "type" "alu1")])
13039 (define_insn "*btrq"
13040   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13041                          (const_int 1)
13042                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13043         (const_int 0))
13044    (clobber (reg:CC FLAGS_REG))]
13045   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13046   "btr{q} %1,%0"
13047   [(set_attr "type" "alu1")])
13049 (define_insn "*btcq"
13050   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13051                          (const_int 1)
13052                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13053         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13054    (clobber (reg:CC FLAGS_REG))]
13055   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13056   "btc{q} %1,%0"
13057   [(set_attr "type" "alu1")])
13059 ;; Allow Nocona to avoid these instructions if a register is available.
13061 (define_peephole2
13062   [(match_scratch:DI 2 "r")
13063    (parallel [(set (zero_extract:DI
13064                      (match_operand:DI 0 "register_operand" "")
13065                      (const_int 1)
13066                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13067                    (const_int 1))
13068               (clobber (reg:CC FLAGS_REG))])]
13069   "TARGET_64BIT && !TARGET_USE_BT"
13070   [(const_int 0)]
13072   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13073   rtx op1;
13075   if (HOST_BITS_PER_WIDE_INT >= 64)
13076     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13077   else if (i < HOST_BITS_PER_WIDE_INT)
13078     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13079   else
13080     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13082   op1 = immed_double_const (lo, hi, DImode);
13083   if (i >= 31)
13084     {
13085       emit_move_insn (operands[2], op1);
13086       op1 = operands[2];
13087     }
13089   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13090   DONE;
13093 (define_peephole2
13094   [(match_scratch:DI 2 "r")
13095    (parallel [(set (zero_extract:DI
13096                      (match_operand:DI 0 "register_operand" "")
13097                      (const_int 1)
13098                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13099                    (const_int 0))
13100               (clobber (reg:CC FLAGS_REG))])]
13101   "TARGET_64BIT && !TARGET_USE_BT"
13102   [(const_int 0)]
13104   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13105   rtx op1;
13107   if (HOST_BITS_PER_WIDE_INT >= 64)
13108     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13109   else if (i < HOST_BITS_PER_WIDE_INT)
13110     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13111   else
13112     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13114   op1 = immed_double_const (~lo, ~hi, DImode);
13115   if (i >= 32)
13116     {
13117       emit_move_insn (operands[2], op1);
13118       op1 = operands[2];
13119     }
13121   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13122   DONE;
13125 (define_peephole2
13126   [(match_scratch:DI 2 "r")
13127    (parallel [(set (zero_extract:DI
13128                      (match_operand:DI 0 "register_operand" "")
13129                      (const_int 1)
13130                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13131               (not:DI (zero_extract:DI
13132                         (match_dup 0) (const_int 1) (match_dup 1))))
13133               (clobber (reg:CC FLAGS_REG))])]
13134   "TARGET_64BIT && !TARGET_USE_BT"
13135   [(const_int 0)]
13137   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13138   rtx op1;
13140   if (HOST_BITS_PER_WIDE_INT >= 64)
13141     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13142   else if (i < HOST_BITS_PER_WIDE_INT)
13143     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13144   else
13145     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13147   op1 = immed_double_const (lo, hi, DImode);
13148   if (i >= 31)
13149     {
13150       emit_move_insn (operands[2], op1);
13151       op1 = operands[2];
13152     }
13154   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13155   DONE;
13158 ;; Store-flag instructions.
13160 ;; For all sCOND expanders, also expand the compare or test insn that
13161 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13163 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13164 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13165 ;; way, which can later delete the movzx if only QImode is needed.
13167 (define_expand "seq"
13168   [(set (match_operand:QI 0 "register_operand" "")
13169         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13170   ""
13171   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13173 (define_expand "sne"
13174   [(set (match_operand:QI 0 "register_operand" "")
13175         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13176   ""
13177   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13179 (define_expand "sgt"
13180   [(set (match_operand:QI 0 "register_operand" "")
13181         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13182   ""
13183   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13185 (define_expand "sgtu"
13186   [(set (match_operand:QI 0 "register_operand" "")
13187         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13188   ""
13189   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13191 (define_expand "slt"
13192   [(set (match_operand:QI 0 "register_operand" "")
13193         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13194   ""
13195   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13197 (define_expand "sltu"
13198   [(set (match_operand:QI 0 "register_operand" "")
13199         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13200   ""
13201   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13203 (define_expand "sge"
13204   [(set (match_operand:QI 0 "register_operand" "")
13205         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13206   ""
13207   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13209 (define_expand "sgeu"
13210   [(set (match_operand:QI 0 "register_operand" "")
13211         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13212   ""
13213   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13215 (define_expand "sle"
13216   [(set (match_operand:QI 0 "register_operand" "")
13217         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13218   ""
13219   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13221 (define_expand "sleu"
13222   [(set (match_operand:QI 0 "register_operand" "")
13223         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13224   ""
13225   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13227 (define_expand "sunordered"
13228   [(set (match_operand:QI 0 "register_operand" "")
13229         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13230   "TARGET_80387 || TARGET_SSE"
13231   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13233 (define_expand "sordered"
13234   [(set (match_operand:QI 0 "register_operand" "")
13235         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13236   "TARGET_80387"
13237   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13239 (define_expand "suneq"
13240   [(set (match_operand:QI 0 "register_operand" "")
13241         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13242   "TARGET_80387 || TARGET_SSE"
13243   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13245 (define_expand "sunge"
13246   [(set (match_operand:QI 0 "register_operand" "")
13247         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13248   "TARGET_80387 || TARGET_SSE"
13249   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13251 (define_expand "sungt"
13252   [(set (match_operand:QI 0 "register_operand" "")
13253         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13254   "TARGET_80387 || TARGET_SSE"
13255   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13257 (define_expand "sunle"
13258   [(set (match_operand:QI 0 "register_operand" "")
13259         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13260   "TARGET_80387 || TARGET_SSE"
13261   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13263 (define_expand "sunlt"
13264   [(set (match_operand:QI 0 "register_operand" "")
13265         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13266   "TARGET_80387 || TARGET_SSE"
13267   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13269 (define_expand "sltgt"
13270   [(set (match_operand:QI 0 "register_operand" "")
13271         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13272   "TARGET_80387 || TARGET_SSE"
13273   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13275 (define_insn "*setcc_1"
13276   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13277         (match_operator:QI 1 "ix86_comparison_operator"
13278           [(reg FLAGS_REG) (const_int 0)]))]
13279   ""
13280   "set%C1\t%0"
13281   [(set_attr "type" "setcc")
13282    (set_attr "mode" "QI")])
13284 (define_insn "*setcc_2"
13285   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13286         (match_operator:QI 1 "ix86_comparison_operator"
13287           [(reg FLAGS_REG) (const_int 0)]))]
13288   ""
13289   "set%C1\t%0"
13290   [(set_attr "type" "setcc")
13291    (set_attr "mode" "QI")])
13293 ;; In general it is not safe to assume too much about CCmode registers,
13294 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13295 ;; conditions this is safe on x86, so help combine not create
13297 ;;      seta    %al
13298 ;;      testb   %al, %al
13299 ;;      sete    %al
13301 (define_split 
13302   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13303         (ne:QI (match_operator 1 "ix86_comparison_operator"
13304                  [(reg FLAGS_REG) (const_int 0)])
13305             (const_int 0)))]
13306   ""
13307   [(set (match_dup 0) (match_dup 1))]
13309   PUT_MODE (operands[1], QImode);
13312 (define_split 
13313   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13314         (ne:QI (match_operator 1 "ix86_comparison_operator"
13315                  [(reg FLAGS_REG) (const_int 0)])
13316             (const_int 0)))]
13317   ""
13318   [(set (match_dup 0) (match_dup 1))]
13320   PUT_MODE (operands[1], QImode);
13323 (define_split 
13324   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13325         (eq:QI (match_operator 1 "ix86_comparison_operator"
13326                  [(reg FLAGS_REG) (const_int 0)])
13327             (const_int 0)))]
13328   ""
13329   [(set (match_dup 0) (match_dup 1))]
13331   rtx new_op1 = copy_rtx (operands[1]);
13332   operands[1] = new_op1;
13333   PUT_MODE (new_op1, QImode);
13334   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13335                                              GET_MODE (XEXP (new_op1, 0))));
13337   /* Make sure that (a) the CCmode we have for the flags is strong
13338      enough for the reversed compare or (b) we have a valid FP compare.  */
13339   if (! ix86_comparison_operator (new_op1, VOIDmode))
13340     FAIL;
13343 (define_split 
13344   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13345         (eq:QI (match_operator 1 "ix86_comparison_operator"
13346                  [(reg FLAGS_REG) (const_int 0)])
13347             (const_int 0)))]
13348   ""
13349   [(set (match_dup 0) (match_dup 1))]
13351   rtx new_op1 = copy_rtx (operands[1]);
13352   operands[1] = new_op1;
13353   PUT_MODE (new_op1, QImode);
13354   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13355                                              GET_MODE (XEXP (new_op1, 0))));
13357   /* Make sure that (a) the CCmode we have for the flags is strong
13358      enough for the reversed compare or (b) we have a valid FP compare.  */
13359   if (! ix86_comparison_operator (new_op1, VOIDmode))
13360     FAIL;
13363 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13364 ;; subsequent logical operations are used to imitate conditional moves.
13365 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13366 ;; it directly.
13368 (define_insn "*sse_setccsf"
13369   [(set (match_operand:SF 0 "register_operand" "=x")
13370         (match_operator:SF 1 "sse_comparison_operator"
13371           [(match_operand:SF 2 "register_operand" "0")
13372            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13373   "TARGET_SSE"
13374   "cmp%D1ss\t{%3, %0|%0, %3}"
13375   [(set_attr "type" "ssecmp")
13376    (set_attr "mode" "SF")])
13378 (define_insn "*sse_setccdf"
13379   [(set (match_operand:DF 0 "register_operand" "=Y")
13380         (match_operator:DF 1 "sse_comparison_operator"
13381           [(match_operand:DF 2 "register_operand" "0")
13382            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13383   "TARGET_SSE2"
13384   "cmp%D1sd\t{%3, %0|%0, %3}"
13385   [(set_attr "type" "ssecmp")
13386    (set_attr "mode" "DF")])
13388 ;; Basic conditional jump instructions.
13389 ;; We ignore the overflow flag for signed branch instructions.
13391 ;; For all bCOND expanders, also expand the compare or test insn that
13392 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13394 (define_expand "beq"
13395   [(set (pc)
13396         (if_then_else (match_dup 1)
13397                       (label_ref (match_operand 0 "" ""))
13398                       (pc)))]
13399   ""
13400   "ix86_expand_branch (EQ, operands[0]); DONE;")
13402 (define_expand "bne"
13403   [(set (pc)
13404         (if_then_else (match_dup 1)
13405                       (label_ref (match_operand 0 "" ""))
13406                       (pc)))]
13407   ""
13408   "ix86_expand_branch (NE, operands[0]); DONE;")
13410 (define_expand "bgt"
13411   [(set (pc)
13412         (if_then_else (match_dup 1)
13413                       (label_ref (match_operand 0 "" ""))
13414                       (pc)))]
13415   ""
13416   "ix86_expand_branch (GT, operands[0]); DONE;")
13418 (define_expand "bgtu"
13419   [(set (pc)
13420         (if_then_else (match_dup 1)
13421                       (label_ref (match_operand 0 "" ""))
13422                       (pc)))]
13423   ""
13424   "ix86_expand_branch (GTU, operands[0]); DONE;")
13426 (define_expand "blt"
13427   [(set (pc)
13428         (if_then_else (match_dup 1)
13429                       (label_ref (match_operand 0 "" ""))
13430                       (pc)))]
13431   ""
13432   "ix86_expand_branch (LT, operands[0]); DONE;")
13434 (define_expand "bltu"
13435   [(set (pc)
13436         (if_then_else (match_dup 1)
13437                       (label_ref (match_operand 0 "" ""))
13438                       (pc)))]
13439   ""
13440   "ix86_expand_branch (LTU, operands[0]); DONE;")
13442 (define_expand "bge"
13443   [(set (pc)
13444         (if_then_else (match_dup 1)
13445                       (label_ref (match_operand 0 "" ""))
13446                       (pc)))]
13447   ""
13448   "ix86_expand_branch (GE, operands[0]); DONE;")
13450 (define_expand "bgeu"
13451   [(set (pc)
13452         (if_then_else (match_dup 1)
13453                       (label_ref (match_operand 0 "" ""))
13454                       (pc)))]
13455   ""
13456   "ix86_expand_branch (GEU, operands[0]); DONE;")
13458 (define_expand "ble"
13459   [(set (pc)
13460         (if_then_else (match_dup 1)
13461                       (label_ref (match_operand 0 "" ""))
13462                       (pc)))]
13463   ""
13464   "ix86_expand_branch (LE, operands[0]); DONE;")
13466 (define_expand "bleu"
13467   [(set (pc)
13468         (if_then_else (match_dup 1)
13469                       (label_ref (match_operand 0 "" ""))
13470                       (pc)))]
13471   ""
13472   "ix86_expand_branch (LEU, operands[0]); DONE;")
13474 (define_expand "bunordered"
13475   [(set (pc)
13476         (if_then_else (match_dup 1)
13477                       (label_ref (match_operand 0 "" ""))
13478                       (pc)))]
13479   "TARGET_80387 || TARGET_SSE_MATH"
13480   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13482 (define_expand "bordered"
13483   [(set (pc)
13484         (if_then_else (match_dup 1)
13485                       (label_ref (match_operand 0 "" ""))
13486                       (pc)))]
13487   "TARGET_80387 || TARGET_SSE_MATH"
13488   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13490 (define_expand "buneq"
13491   [(set (pc)
13492         (if_then_else (match_dup 1)
13493                       (label_ref (match_operand 0 "" ""))
13494                       (pc)))]
13495   "TARGET_80387 || TARGET_SSE_MATH"
13496   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13498 (define_expand "bunge"
13499   [(set (pc)
13500         (if_then_else (match_dup 1)
13501                       (label_ref (match_operand 0 "" ""))
13502                       (pc)))]
13503   "TARGET_80387 || TARGET_SSE_MATH"
13504   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13506 (define_expand "bungt"
13507   [(set (pc)
13508         (if_then_else (match_dup 1)
13509                       (label_ref (match_operand 0 "" ""))
13510                       (pc)))]
13511   "TARGET_80387 || TARGET_SSE_MATH"
13512   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13514 (define_expand "bunle"
13515   [(set (pc)
13516         (if_then_else (match_dup 1)
13517                       (label_ref (match_operand 0 "" ""))
13518                       (pc)))]
13519   "TARGET_80387 || TARGET_SSE_MATH"
13520   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13522 (define_expand "bunlt"
13523   [(set (pc)
13524         (if_then_else (match_dup 1)
13525                       (label_ref (match_operand 0 "" ""))
13526                       (pc)))]
13527   "TARGET_80387 || TARGET_SSE_MATH"
13528   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13530 (define_expand "bltgt"
13531   [(set (pc)
13532         (if_then_else (match_dup 1)
13533                       (label_ref (match_operand 0 "" ""))
13534                       (pc)))]
13535   "TARGET_80387 || TARGET_SSE_MATH"
13536   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13538 (define_insn "*jcc_1"
13539   [(set (pc)
13540         (if_then_else (match_operator 1 "ix86_comparison_operator"
13541                                       [(reg FLAGS_REG) (const_int 0)])
13542                       (label_ref (match_operand 0 "" ""))
13543                       (pc)))]
13544   ""
13545   "%+j%C1\t%l0"
13546   [(set_attr "type" "ibr")
13547    (set_attr "modrm" "0")
13548    (set (attr "length")
13549            (if_then_else (and (ge (minus (match_dup 0) (pc))
13550                                   (const_int -126))
13551                               (lt (minus (match_dup 0) (pc))
13552                                   (const_int 128)))
13553              (const_int 2)
13554              (const_int 6)))])
13556 (define_insn "*jcc_2"
13557   [(set (pc)
13558         (if_then_else (match_operator 1 "ix86_comparison_operator"
13559                                       [(reg FLAGS_REG) (const_int 0)])
13560                       (pc)
13561                       (label_ref (match_operand 0 "" ""))))]
13562   ""
13563   "%+j%c1\t%l0"
13564   [(set_attr "type" "ibr")
13565    (set_attr "modrm" "0")
13566    (set (attr "length")
13567            (if_then_else (and (ge (minus (match_dup 0) (pc))
13568                                   (const_int -126))
13569                               (lt (minus (match_dup 0) (pc))
13570                                   (const_int 128)))
13571              (const_int 2)
13572              (const_int 6)))])
13574 ;; In general it is not safe to assume too much about CCmode registers,
13575 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13576 ;; conditions this is safe on x86, so help combine not create
13578 ;;      seta    %al
13579 ;;      testb   %al, %al
13580 ;;      je      Lfoo
13582 (define_split 
13583   [(set (pc)
13584         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13585                                       [(reg FLAGS_REG) (const_int 0)])
13586                           (const_int 0))
13587                       (label_ref (match_operand 1 "" ""))
13588                       (pc)))]
13589   ""
13590   [(set (pc)
13591         (if_then_else (match_dup 0)
13592                       (label_ref (match_dup 1))
13593                       (pc)))]
13595   PUT_MODE (operands[0], VOIDmode);
13597   
13598 (define_split 
13599   [(set (pc)
13600         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13601                                       [(reg FLAGS_REG) (const_int 0)])
13602                           (const_int 0))
13603                       (label_ref (match_operand 1 "" ""))
13604                       (pc)))]
13605   ""
13606   [(set (pc)
13607         (if_then_else (match_dup 0)
13608                       (label_ref (match_dup 1))
13609                       (pc)))]
13611   rtx new_op0 = copy_rtx (operands[0]);
13612   operands[0] = new_op0;
13613   PUT_MODE (new_op0, VOIDmode);
13614   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13615                                              GET_MODE (XEXP (new_op0, 0))));
13617   /* Make sure that (a) the CCmode we have for the flags is strong
13618      enough for the reversed compare or (b) we have a valid FP compare.  */
13619   if (! ix86_comparison_operator (new_op0, VOIDmode))
13620     FAIL;
13623 ;; Define combination compare-and-branch fp compare instructions to use
13624 ;; during early optimization.  Splitting the operation apart early makes
13625 ;; for bad code when we want to reverse the operation.
13627 (define_insn "*fp_jcc_1_mixed"
13628   [(set (pc)
13629         (if_then_else (match_operator 0 "comparison_operator"
13630                         [(match_operand 1 "register_operand" "f,x")
13631                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13632           (label_ref (match_operand 3 "" ""))
13633           (pc)))
13634    (clobber (reg:CCFP FPSR_REG))
13635    (clobber (reg:CCFP FLAGS_REG))]
13636   "TARGET_MIX_SSE_I387
13637    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13638    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13639    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13640   "#")
13642 (define_insn "*fp_jcc_1_sse"
13643   [(set (pc)
13644         (if_then_else (match_operator 0 "comparison_operator"
13645                         [(match_operand 1 "register_operand" "x")
13646                          (match_operand 2 "nonimmediate_operand" "xm")])
13647           (label_ref (match_operand 3 "" ""))
13648           (pc)))
13649    (clobber (reg:CCFP FPSR_REG))
13650    (clobber (reg:CCFP FLAGS_REG))]
13651   "TARGET_SSE_MATH
13652    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13653    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13654    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13655   "#")
13657 (define_insn "*fp_jcc_1_387"
13658   [(set (pc)
13659         (if_then_else (match_operator 0 "comparison_operator"
13660                         [(match_operand 1 "register_operand" "f")
13661                          (match_operand 2 "register_operand" "f")])
13662           (label_ref (match_operand 3 "" ""))
13663           (pc)))
13664    (clobber (reg:CCFP FPSR_REG))
13665    (clobber (reg:CCFP FLAGS_REG))]
13666   "TARGET_CMOVE && TARGET_80387
13667    && FLOAT_MODE_P (GET_MODE (operands[1]))
13668    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13669    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13670   "#")
13672 (define_insn "*fp_jcc_2_mixed"
13673   [(set (pc)
13674         (if_then_else (match_operator 0 "comparison_operator"
13675                         [(match_operand 1 "register_operand" "f,x")
13676                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13677           (pc)
13678           (label_ref (match_operand 3 "" ""))))
13679    (clobber (reg:CCFP FPSR_REG))
13680    (clobber (reg:CCFP FLAGS_REG))]
13681   "TARGET_MIX_SSE_I387
13682    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13683    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13684    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13685   "#")
13687 (define_insn "*fp_jcc_2_sse"
13688   [(set (pc)
13689         (if_then_else (match_operator 0 "comparison_operator"
13690                         [(match_operand 1 "register_operand" "x")
13691                          (match_operand 2 "nonimmediate_operand" "xm")])
13692           (pc)
13693           (label_ref (match_operand 3 "" ""))))
13694    (clobber (reg:CCFP FPSR_REG))
13695    (clobber (reg:CCFP FLAGS_REG))]
13696   "TARGET_SSE_MATH
13697    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13698    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13699    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13700   "#")
13702 (define_insn "*fp_jcc_2_387"
13703   [(set (pc)
13704         (if_then_else (match_operator 0 "comparison_operator"
13705                         [(match_operand 1 "register_operand" "f")
13706                          (match_operand 2 "register_operand" "f")])
13707           (pc)
13708           (label_ref (match_operand 3 "" ""))))
13709    (clobber (reg:CCFP FPSR_REG))
13710    (clobber (reg:CCFP FLAGS_REG))]
13711   "TARGET_CMOVE && TARGET_80387
13712    && FLOAT_MODE_P (GET_MODE (operands[1]))
13713    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13714    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13715   "#")
13717 (define_insn "*fp_jcc_3_387"
13718   [(set (pc)
13719         (if_then_else (match_operator 0 "comparison_operator"
13720                         [(match_operand 1 "register_operand" "f")
13721                          (match_operand 2 "nonimmediate_operand" "fm")])
13722           (label_ref (match_operand 3 "" ""))
13723           (pc)))
13724    (clobber (reg:CCFP FPSR_REG))
13725    (clobber (reg:CCFP FLAGS_REG))
13726    (clobber (match_scratch:HI 4 "=a"))]
13727   "TARGET_80387
13728    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13729    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13730    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13731    && SELECT_CC_MODE (GET_CODE (operands[0]),
13732                       operands[1], operands[2]) == CCFPmode
13733    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13734   "#")
13736 (define_insn "*fp_jcc_4_387"
13737   [(set (pc)
13738         (if_then_else (match_operator 0 "comparison_operator"
13739                         [(match_operand 1 "register_operand" "f")
13740                          (match_operand 2 "nonimmediate_operand" "fm")])
13741           (pc)
13742           (label_ref (match_operand 3 "" ""))))
13743    (clobber (reg:CCFP FPSR_REG))
13744    (clobber (reg:CCFP FLAGS_REG))
13745    (clobber (match_scratch:HI 4 "=a"))]
13746   "TARGET_80387
13747    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13748    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13749    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13750    && SELECT_CC_MODE (GET_CODE (operands[0]),
13751                       operands[1], operands[2]) == CCFPmode
13752    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13753   "#")
13755 (define_insn "*fp_jcc_5_387"
13756   [(set (pc)
13757         (if_then_else (match_operator 0 "comparison_operator"
13758                         [(match_operand 1 "register_operand" "f")
13759                          (match_operand 2 "register_operand" "f")])
13760           (label_ref (match_operand 3 "" ""))
13761           (pc)))
13762    (clobber (reg:CCFP FPSR_REG))
13763    (clobber (reg:CCFP FLAGS_REG))
13764    (clobber (match_scratch:HI 4 "=a"))]
13765   "TARGET_80387
13766    && FLOAT_MODE_P (GET_MODE (operands[1]))
13767    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13768    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13769   "#")
13771 (define_insn "*fp_jcc_6_387"
13772   [(set (pc)
13773         (if_then_else (match_operator 0 "comparison_operator"
13774                         [(match_operand 1 "register_operand" "f")
13775                          (match_operand 2 "register_operand" "f")])
13776           (pc)
13777           (label_ref (match_operand 3 "" ""))))
13778    (clobber (reg:CCFP FPSR_REG))
13779    (clobber (reg:CCFP FLAGS_REG))
13780    (clobber (match_scratch:HI 4 "=a"))]
13781   "TARGET_80387
13782    && FLOAT_MODE_P (GET_MODE (operands[1]))
13783    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13784    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13785   "#")
13787 (define_insn "*fp_jcc_7_387"
13788   [(set (pc)
13789         (if_then_else (match_operator 0 "comparison_operator"
13790                         [(match_operand 1 "register_operand" "f")
13791                          (match_operand 2 "const0_operand" "X")])
13792           (label_ref (match_operand 3 "" ""))
13793           (pc)))
13794    (clobber (reg:CCFP FPSR_REG))
13795    (clobber (reg:CCFP FLAGS_REG))
13796    (clobber (match_scratch:HI 4 "=a"))]
13797   "TARGET_80387
13798    && FLOAT_MODE_P (GET_MODE (operands[1]))
13799    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13800    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13801    && SELECT_CC_MODE (GET_CODE (operands[0]),
13802                       operands[1], operands[2]) == CCFPmode
13803    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13804   "#")
13806 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13807 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13808 ;; with a precedence over other operators and is always put in the first
13809 ;; place. Swap condition and operands to match ficom instruction.
13811 (define_insn "*fp_jcc_8<mode>_387"
13812   [(set (pc)
13813         (if_then_else (match_operator 0 "comparison_operator"
13814                         [(match_operator 1 "float_operator"
13815                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13816                            (match_operand 3 "register_operand" "f,f")])
13817           (label_ref (match_operand 4 "" ""))
13818           (pc)))
13819    (clobber (reg:CCFP FPSR_REG))
13820    (clobber (reg:CCFP FLAGS_REG))
13821    (clobber (match_scratch:HI 5 "=a,a"))]
13822   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13823    && FLOAT_MODE_P (GET_MODE (operands[3]))
13824    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13825    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13826    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13827    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13828   "#")
13830 (define_split
13831   [(set (pc)
13832         (if_then_else (match_operator 0 "comparison_operator"
13833                         [(match_operand 1 "register_operand" "")
13834                          (match_operand 2 "nonimmediate_operand" "")])
13835           (match_operand 3 "" "")
13836           (match_operand 4 "" "")))
13837    (clobber (reg:CCFP FPSR_REG))
13838    (clobber (reg:CCFP FLAGS_REG))]
13839   "reload_completed"
13840   [(const_int 0)]
13842   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13843                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13844   DONE;
13847 (define_split
13848   [(set (pc)
13849         (if_then_else (match_operator 0 "comparison_operator"
13850                         [(match_operand 1 "register_operand" "")
13851                          (match_operand 2 "general_operand" "")])
13852           (match_operand 3 "" "")
13853           (match_operand 4 "" "")))
13854    (clobber (reg:CCFP FPSR_REG))
13855    (clobber (reg:CCFP FLAGS_REG))
13856    (clobber (match_scratch:HI 5 "=a"))]
13857   "reload_completed"
13858   [(const_int 0)]
13860   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13861                         operands[3], operands[4], operands[5], NULL_RTX);
13862   DONE;
13865 (define_split
13866   [(set (pc)
13867         (if_then_else (match_operator 0 "comparison_operator"
13868                         [(match_operator 1 "float_operator"
13869                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13870                            (match_operand 3 "register_operand" "")])
13871           (match_operand 4 "" "")
13872           (match_operand 5 "" "")))
13873    (clobber (reg:CCFP FPSR_REG))
13874    (clobber (reg:CCFP FLAGS_REG))
13875    (clobber (match_scratch:HI 6 "=a"))]
13876   "reload_completed"
13877   [(const_int 0)]
13879   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13880   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13881                         operands[3], operands[7],
13882                         operands[4], operands[5], operands[6], NULL_RTX);
13883   DONE;
13886 ;; %%% Kill this when reload knows how to do it.
13887 (define_split
13888   [(set (pc)
13889         (if_then_else (match_operator 0 "comparison_operator"
13890                         [(match_operator 1 "float_operator"
13891                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13892                            (match_operand 3 "register_operand" "")])
13893           (match_operand 4 "" "")
13894           (match_operand 5 "" "")))
13895    (clobber (reg:CCFP FPSR_REG))
13896    (clobber (reg:CCFP FLAGS_REG))
13897    (clobber (match_scratch:HI 6 "=a"))]
13898   "reload_completed"
13899   [(const_int 0)]
13901   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13902   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13903   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13904                         operands[3], operands[7],
13905                         operands[4], operands[5], operands[6], operands[2]);
13906   DONE;
13909 ;; Unconditional and other jump instructions
13911 (define_insn "jump"
13912   [(set (pc)
13913         (label_ref (match_operand 0 "" "")))]
13914   ""
13915   "jmp\t%l0"
13916   [(set_attr "type" "ibr")
13917    (set (attr "length")
13918            (if_then_else (and (ge (minus (match_dup 0) (pc))
13919                                   (const_int -126))
13920                               (lt (minus (match_dup 0) (pc))
13921                                   (const_int 128)))
13922              (const_int 2)
13923              (const_int 5)))
13924    (set_attr "modrm" "0")])
13926 (define_expand "indirect_jump"
13927   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13928   ""
13929   "")
13931 (define_insn "*indirect_jump"
13932   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13933   "!TARGET_64BIT"
13934   "jmp\t%A0"
13935   [(set_attr "type" "ibr")
13936    (set_attr "length_immediate" "0")])
13938 (define_insn "*indirect_jump_rtx64"
13939   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13940   "TARGET_64BIT"
13941   "jmp\t%A0"
13942   [(set_attr "type" "ibr")
13943    (set_attr "length_immediate" "0")])
13945 (define_expand "tablejump"
13946   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13947               (use (label_ref (match_operand 1 "" "")))])]
13948   ""
13950   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13951      relative.  Convert the relative address to an absolute address.  */
13952   if (flag_pic)
13953     {
13954       rtx op0, op1;
13955       enum rtx_code code;
13957       if (TARGET_64BIT)
13958         {
13959           code = PLUS;
13960           op0 = operands[0];
13961           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13962         }
13963       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13964         {
13965           code = PLUS;
13966           op0 = operands[0];
13967           op1 = pic_offset_table_rtx;
13968         }
13969       else
13970         {
13971           code = MINUS;
13972           op0 = pic_offset_table_rtx;
13973           op1 = operands[0];
13974         }
13976       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13977                                          OPTAB_DIRECT);
13978     }
13981 (define_insn "*tablejump_1"
13982   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13983    (use (label_ref (match_operand 1 "" "")))]
13984   "!TARGET_64BIT"
13985   "jmp\t%A0"
13986   [(set_attr "type" "ibr")
13987    (set_attr "length_immediate" "0")])
13989 (define_insn "*tablejump_1_rtx64"
13990   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13991    (use (label_ref (match_operand 1 "" "")))]
13992   "TARGET_64BIT"
13993   "jmp\t%A0"
13994   [(set_attr "type" "ibr")
13995    (set_attr "length_immediate" "0")])
13997 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13999 (define_peephole2
14000   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14001    (set (match_operand:QI 1 "register_operand" "")
14002         (match_operator:QI 2 "ix86_comparison_operator"
14003           [(reg FLAGS_REG) (const_int 0)]))
14004    (set (match_operand 3 "q_regs_operand" "")
14005         (zero_extend (match_dup 1)))]
14006   "(peep2_reg_dead_p (3, operands[1])
14007     || operands_match_p (operands[1], operands[3]))
14008    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14009   [(set (match_dup 4) (match_dup 0))
14010    (set (strict_low_part (match_dup 5))
14011         (match_dup 2))]
14013   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14014   operands[5] = gen_lowpart (QImode, operands[3]);
14015   ix86_expand_clear (operands[3]);
14018 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14020 (define_peephole2
14021   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14022    (set (match_operand:QI 1 "register_operand" "")
14023         (match_operator:QI 2 "ix86_comparison_operator"
14024           [(reg FLAGS_REG) (const_int 0)]))
14025    (parallel [(set (match_operand 3 "q_regs_operand" "")
14026                    (zero_extend (match_dup 1)))
14027               (clobber (reg:CC FLAGS_REG))])]
14028   "(peep2_reg_dead_p (3, operands[1])
14029     || operands_match_p (operands[1], operands[3]))
14030    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14031   [(set (match_dup 4) (match_dup 0))
14032    (set (strict_low_part (match_dup 5))
14033         (match_dup 2))]
14035   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14036   operands[5] = gen_lowpart (QImode, operands[3]);
14037   ix86_expand_clear (operands[3]);
14040 ;; Call instructions.
14042 ;; The predicates normally associated with named expanders are not properly
14043 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14044 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14046 ;; Call subroutine returning no value.
14048 (define_expand "call_pop"
14049   [(parallel [(call (match_operand:QI 0 "" "")
14050                     (match_operand:SI 1 "" ""))
14051               (set (reg:SI SP_REG)
14052                    (plus:SI (reg:SI SP_REG)
14053                             (match_operand:SI 3 "" "")))])]
14054   "!TARGET_64BIT"
14056   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14057   DONE;
14060 (define_insn "*call_pop_0"
14061   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14062          (match_operand:SI 1 "" ""))
14063    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14064                             (match_operand:SI 2 "immediate_operand" "")))]
14065   "!TARGET_64BIT"
14067   if (SIBLING_CALL_P (insn))
14068     return "jmp\t%P0";
14069   else
14070     return "call\t%P0";
14072   [(set_attr "type" "call")])
14073   
14074 (define_insn "*call_pop_1"
14075   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14076          (match_operand:SI 1 "" ""))
14077    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14078                             (match_operand:SI 2 "immediate_operand" "i")))]
14079   "!TARGET_64BIT"
14081   if (constant_call_address_operand (operands[0], Pmode))
14082     {
14083       if (SIBLING_CALL_P (insn))
14084         return "jmp\t%P0";
14085       else
14086         return "call\t%P0";
14087     }
14088   if (SIBLING_CALL_P (insn))
14089     return "jmp\t%A0";
14090   else
14091     return "call\t%A0";
14093   [(set_attr "type" "call")])
14095 (define_expand "call"
14096   [(call (match_operand:QI 0 "" "")
14097          (match_operand 1 "" ""))
14098    (use (match_operand 2 "" ""))]
14099   ""
14101   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14102   DONE;
14105 (define_expand "sibcall"
14106   [(call (match_operand:QI 0 "" "")
14107          (match_operand 1 "" ""))
14108    (use (match_operand 2 "" ""))]
14109   ""
14111   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14112   DONE;
14115 (define_insn "*call_0"
14116   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14117          (match_operand 1 "" ""))]
14118   ""
14120   if (SIBLING_CALL_P (insn))
14121     return "jmp\t%P0";
14122   else
14123     return "call\t%P0";
14125   [(set_attr "type" "call")])
14127 (define_insn "*call_1"
14128   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14129          (match_operand 1 "" ""))]
14130   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14132   if (constant_call_address_operand (operands[0], Pmode))
14133     return "call\t%P0";
14134   return "call\t%A0";
14136   [(set_attr "type" "call")])
14138 (define_insn "*sibcall_1"
14139   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14140          (match_operand 1 "" ""))]
14141   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14143   if (constant_call_address_operand (operands[0], Pmode))
14144     return "jmp\t%P0";
14145   return "jmp\t%A0";
14147   [(set_attr "type" "call")])
14149 (define_insn "*call_1_rex64"
14150   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14151          (match_operand 1 "" ""))]
14152   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14154   if (constant_call_address_operand (operands[0], Pmode))
14155     return "call\t%P0";
14156   return "call\t%A0";
14158   [(set_attr "type" "call")])
14160 (define_insn "*sibcall_1_rex64"
14161   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14162          (match_operand 1 "" ""))]
14163   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14164   "jmp\t%P0"
14165   [(set_attr "type" "call")])
14167 (define_insn "*sibcall_1_rex64_v"
14168   [(call (mem:QI (reg:DI R11_REG))
14169          (match_operand 0 "" ""))]
14170   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14171   "jmp\t*%%r11"
14172   [(set_attr "type" "call")])
14175 ;; Call subroutine, returning value in operand 0
14177 (define_expand "call_value_pop"
14178   [(parallel [(set (match_operand 0 "" "")
14179                    (call (match_operand:QI 1 "" "")
14180                          (match_operand:SI 2 "" "")))
14181               (set (reg:SI SP_REG)
14182                    (plus:SI (reg:SI SP_REG)
14183                             (match_operand:SI 4 "" "")))])]
14184   "!TARGET_64BIT"
14186   ix86_expand_call (operands[0], operands[1], operands[2],
14187                     operands[3], operands[4], 0);
14188   DONE;
14191 (define_expand "call_value"
14192   [(set (match_operand 0 "" "")
14193         (call (match_operand:QI 1 "" "")
14194               (match_operand:SI 2 "" "")))
14195    (use (match_operand:SI 3 "" ""))]
14196   ;; Operand 2 not used on the i386.
14197   ""
14199   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14200   DONE;
14203 (define_expand "sibcall_value"
14204   [(set (match_operand 0 "" "")
14205         (call (match_operand:QI 1 "" "")
14206               (match_operand:SI 2 "" "")))
14207    (use (match_operand:SI 3 "" ""))]
14208   ;; Operand 2 not used on the i386.
14209   ""
14211   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14212   DONE;
14215 ;; Call subroutine returning any type.
14217 (define_expand "untyped_call"
14218   [(parallel [(call (match_operand 0 "" "")
14219                     (const_int 0))
14220               (match_operand 1 "" "")
14221               (match_operand 2 "" "")])]
14222   ""
14224   int i;
14226   /* In order to give reg-stack an easier job in validating two
14227      coprocessor registers as containing a possible return value,
14228      simply pretend the untyped call returns a complex long double
14229      value.  */
14231   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14232                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14233                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14234                     NULL, 0);
14236   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14237     {
14238       rtx set = XVECEXP (operands[2], 0, i);
14239       emit_move_insn (SET_DEST (set), SET_SRC (set));
14240     }
14242   /* The optimizer does not know that the call sets the function value
14243      registers we stored in the result block.  We avoid problems by
14244      claiming that all hard registers are used and clobbered at this
14245      point.  */
14246   emit_insn (gen_blockage (const0_rtx));
14248   DONE;
14251 ;; Prologue and epilogue instructions
14253 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14254 ;; all of memory.  This blocks insns from being moved across this point.
14256 (define_insn "blockage"
14257   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14258   ""
14259   ""
14260   [(set_attr "length" "0")])
14262 ;; Insn emitted into the body of a function to return from a function.
14263 ;; This is only done if the function's epilogue is known to be simple.
14264 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14266 (define_expand "return"
14267   [(return)]
14268   "ix86_can_use_return_insn_p ()"
14270   if (current_function_pops_args)
14271     {
14272       rtx popc = GEN_INT (current_function_pops_args);
14273       emit_jump_insn (gen_return_pop_internal (popc));
14274       DONE;
14275     }
14278 (define_insn "return_internal"
14279   [(return)]
14280   "reload_completed"
14281   "ret"
14282   [(set_attr "length" "1")
14283    (set_attr "length_immediate" "0")
14284    (set_attr "modrm" "0")])
14286 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14287 ;; instruction Athlon and K8 have.
14289 (define_insn "return_internal_long"
14290   [(return)
14291    (unspec [(const_int 0)] UNSPEC_REP)]
14292   "reload_completed"
14293   "rep {;} ret"
14294   [(set_attr "length" "1")
14295    (set_attr "length_immediate" "0")
14296    (set_attr "prefix_rep" "1")
14297    (set_attr "modrm" "0")])
14299 (define_insn "return_pop_internal"
14300   [(return)
14301    (use (match_operand:SI 0 "const_int_operand" ""))]
14302   "reload_completed"
14303   "ret\t%0"
14304   [(set_attr "length" "3")
14305    (set_attr "length_immediate" "2")
14306    (set_attr "modrm" "0")])
14308 (define_insn "return_indirect_internal"
14309   [(return)
14310    (use (match_operand:SI 0 "register_operand" "r"))]
14311   "reload_completed"
14312   "jmp\t%A0"
14313   [(set_attr "type" "ibr")
14314    (set_attr "length_immediate" "0")])
14316 (define_insn "nop"
14317   [(const_int 0)]
14318   ""
14319   "nop"
14320   [(set_attr "length" "1")
14321    (set_attr "length_immediate" "0")
14322    (set_attr "modrm" "0")])
14324 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14325 ;; branch prediction penalty for the third jump in a 16-byte
14326 ;; block on K8.
14328 (define_insn "align"
14329   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14330   ""
14332 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14333   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14334 #else
14335   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14336      The align insn is used to avoid 3 jump instructions in the row to improve
14337      branch prediction and the benefits hardly outweigh the cost of extra 8
14338      nops on the average inserted by full alignment pseudo operation.  */
14339 #endif
14340   return "";
14342   [(set_attr "length" "16")])
14344 (define_expand "prologue"
14345   [(const_int 1)]
14346   ""
14347   "ix86_expand_prologue (); DONE;")
14349 (define_insn "set_got"
14350   [(set (match_operand:SI 0 "register_operand" "=r")
14351         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14352    (clobber (reg:CC FLAGS_REG))]
14353   "!TARGET_64BIT"
14354   { return output_set_got (operands[0], NULL_RTX); }
14355   [(set_attr "type" "multi")
14356    (set_attr "length" "12")])
14358 (define_insn "set_got_labelled"
14359   [(set (match_operand:SI 0 "register_operand" "=r")
14360         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14361          UNSPEC_SET_GOT))
14362    (clobber (reg:CC FLAGS_REG))]
14363   "!TARGET_64BIT"
14364   { return output_set_got (operands[0], operands[1]); }
14365   [(set_attr "type" "multi")
14366    (set_attr "length" "12")])
14368 (define_insn "set_got_rex64"
14369   [(set (match_operand:DI 0 "register_operand" "=r")
14370         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14371   "TARGET_64BIT"
14372   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14373   [(set_attr "type" "lea")
14374    (set_attr "length" "6")])
14376 (define_expand "epilogue"
14377   [(const_int 1)]
14378   ""
14379   "ix86_expand_epilogue (1); DONE;")
14381 (define_expand "sibcall_epilogue"
14382   [(const_int 1)]
14383   ""
14384   "ix86_expand_epilogue (0); DONE;")
14386 (define_expand "eh_return"
14387   [(use (match_operand 0 "register_operand" ""))]
14388   ""
14390   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14392   /* Tricky bit: we write the address of the handler to which we will
14393      be returning into someone else's stack frame, one word below the
14394      stack address we wish to restore.  */
14395   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14396   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14397   tmp = gen_rtx_MEM (Pmode, tmp);
14398   emit_move_insn (tmp, ra);
14400   if (Pmode == SImode)
14401     emit_jump_insn (gen_eh_return_si (sa));
14402   else
14403     emit_jump_insn (gen_eh_return_di (sa));
14404   emit_barrier ();
14405   DONE;
14408 (define_insn_and_split "eh_return_si"
14409   [(set (pc) 
14410         (unspec [(match_operand:SI 0 "register_operand" "c")]
14411                  UNSPEC_EH_RETURN))]
14412   "!TARGET_64BIT"
14413   "#"
14414   "reload_completed"
14415   [(const_int 1)]
14416   "ix86_expand_epilogue (2); DONE;")
14418 (define_insn_and_split "eh_return_di"
14419   [(set (pc) 
14420         (unspec [(match_operand:DI 0 "register_operand" "c")]
14421                  UNSPEC_EH_RETURN))]
14422   "TARGET_64BIT"
14423   "#"
14424   "reload_completed"
14425   [(const_int 1)]
14426   "ix86_expand_epilogue (2); DONE;")
14428 (define_insn "leave"
14429   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14430    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14431    (clobber (mem:BLK (scratch)))]
14432   "!TARGET_64BIT"
14433   "leave"
14434   [(set_attr "type" "leave")])
14436 (define_insn "leave_rex64"
14437   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14438    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14439    (clobber (mem:BLK (scratch)))]
14440   "TARGET_64BIT"
14441   "leave"
14442   [(set_attr "type" "leave")])
14444 (define_expand "ffssi2"
14445   [(parallel
14446      [(set (match_operand:SI 0 "register_operand" "") 
14447            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14448       (clobber (match_scratch:SI 2 ""))
14449       (clobber (reg:CC FLAGS_REG))])]
14450   ""
14451   "")
14453 (define_insn_and_split "*ffs_cmove"
14454   [(set (match_operand:SI 0 "register_operand" "=r") 
14455         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14456    (clobber (match_scratch:SI 2 "=&r"))
14457    (clobber (reg:CC FLAGS_REG))]
14458   "TARGET_CMOVE"
14459   "#"
14460   "&& reload_completed"
14461   [(set (match_dup 2) (const_int -1))
14462    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14463               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14464    (set (match_dup 0) (if_then_else:SI
14465                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14466                         (match_dup 2)
14467                         (match_dup 0)))
14468    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14469               (clobber (reg:CC FLAGS_REG))])]
14470   "")
14472 (define_insn_and_split "*ffs_no_cmove"
14473   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14474         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14475    (clobber (match_scratch:SI 2 "=&q"))
14476    (clobber (reg:CC FLAGS_REG))]
14477   ""
14478   "#"
14479   "reload_completed"
14480   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14481               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14482    (set (strict_low_part (match_dup 3))
14483         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14484    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14485               (clobber (reg:CC FLAGS_REG))])
14486    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14487               (clobber (reg:CC FLAGS_REG))])
14488    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14489               (clobber (reg:CC FLAGS_REG))])]
14491   operands[3] = gen_lowpart (QImode, operands[2]);
14492   ix86_expand_clear (operands[2]);
14495 (define_insn "*ffssi_1"
14496   [(set (reg:CCZ FLAGS_REG)
14497         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14498                      (const_int 0)))
14499    (set (match_operand:SI 0 "register_operand" "=r")
14500         (ctz:SI (match_dup 1)))]
14501   ""
14502   "bsf{l}\t{%1, %0|%0, %1}"
14503   [(set_attr "prefix_0f" "1")])
14505 (define_expand "ffsdi2"
14506   [(parallel
14507      [(set (match_operand:DI 0 "register_operand" "") 
14508            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14509       (clobber (match_scratch:DI 2 ""))
14510       (clobber (reg:CC FLAGS_REG))])]
14511   "TARGET_64BIT && TARGET_CMOVE"
14512   "")
14514 (define_insn_and_split "*ffs_rex64"
14515   [(set (match_operand:DI 0 "register_operand" "=r") 
14516         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14517    (clobber (match_scratch:DI 2 "=&r"))
14518    (clobber (reg:CC FLAGS_REG))]
14519   "TARGET_64BIT && TARGET_CMOVE"
14520   "#"
14521   "&& reload_completed"
14522   [(set (match_dup 2) (const_int -1))
14523    (parallel [(set (reg:CCZ FLAGS_REG)
14524                    (compare:CCZ (match_dup 1) (const_int 0)))
14525               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14526    (set (match_dup 0) (if_then_else:DI
14527                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14528                         (match_dup 2)
14529                         (match_dup 0)))
14530    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14531               (clobber (reg:CC FLAGS_REG))])]
14532   "")
14534 (define_insn "*ffsdi_1"
14535   [(set (reg:CCZ FLAGS_REG)
14536         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14537                      (const_int 0)))
14538    (set (match_operand:DI 0 "register_operand" "=r")
14539         (ctz:DI (match_dup 1)))]
14540   "TARGET_64BIT"
14541   "bsf{q}\t{%1, %0|%0, %1}"
14542   [(set_attr "prefix_0f" "1")])
14544 (define_insn "ctzsi2"
14545   [(set (match_operand:SI 0 "register_operand" "=r")
14546         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14547    (clobber (reg:CC FLAGS_REG))]
14548   ""
14549   "bsf{l}\t{%1, %0|%0, %1}"
14550   [(set_attr "prefix_0f" "1")])
14552 (define_insn "ctzdi2"
14553   [(set (match_operand:DI 0 "register_operand" "=r")
14554         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14555    (clobber (reg:CC FLAGS_REG))]
14556   "TARGET_64BIT"
14557   "bsf{q}\t{%1, %0|%0, %1}"
14558   [(set_attr "prefix_0f" "1")])
14560 (define_expand "clzsi2"
14561   [(parallel
14562      [(set (match_operand:SI 0 "register_operand" "")
14563            (minus:SI (const_int 31)
14564                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14565       (clobber (reg:CC FLAGS_REG))])
14566    (parallel
14567      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14568       (clobber (reg:CC FLAGS_REG))])]
14569   ""
14570   "")
14572 (define_insn "*bsr"
14573   [(set (match_operand:SI 0 "register_operand" "=r")
14574         (minus:SI (const_int 31)
14575                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14576    (clobber (reg:CC FLAGS_REG))]
14577   ""
14578   "bsr{l}\t{%1, %0|%0, %1}"
14579   [(set_attr "prefix_0f" "1")])
14581 (define_expand "clzdi2"
14582   [(parallel
14583      [(set (match_operand:DI 0 "register_operand" "")
14584            (minus:DI (const_int 63)
14585                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14586       (clobber (reg:CC FLAGS_REG))])
14587    (parallel
14588      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14589       (clobber (reg:CC FLAGS_REG))])]
14590   "TARGET_64BIT"
14591   "")
14593 (define_insn "*bsr_rex64"
14594   [(set (match_operand:DI 0 "register_operand" "=r")
14595         (minus:DI (const_int 63)
14596                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14597    (clobber (reg:CC FLAGS_REG))]
14598   "TARGET_64BIT"
14599   "bsr{q}\t{%1, %0|%0, %1}"
14600   [(set_attr "prefix_0f" "1")])
14602 ;; Thread-local storage patterns for ELF.
14604 ;; Note that these code sequences must appear exactly as shown
14605 ;; in order to allow linker relaxation.
14607 (define_insn "*tls_global_dynamic_32_gnu"
14608   [(set (match_operand:SI 0 "register_operand" "=a")
14609         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14610                     (match_operand:SI 2 "tls_symbolic_operand" "")
14611                     (match_operand:SI 3 "call_insn_operand" "")]
14612                     UNSPEC_TLS_GD))
14613    (clobber (match_scratch:SI 4 "=d"))
14614    (clobber (match_scratch:SI 5 "=c"))
14615    (clobber (reg:CC FLAGS_REG))]
14616   "!TARGET_64BIT && TARGET_GNU_TLS"
14617   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14618   [(set_attr "type" "multi")
14619    (set_attr "length" "12")])
14621 (define_insn "*tls_global_dynamic_32_sun"
14622   [(set (match_operand:SI 0 "register_operand" "=a")
14623         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14624                     (match_operand:SI 2 "tls_symbolic_operand" "")
14625                     (match_operand:SI 3 "call_insn_operand" "")]
14626                     UNSPEC_TLS_GD))
14627    (clobber (match_scratch:SI 4 "=d"))
14628    (clobber (match_scratch:SI 5 "=c"))
14629    (clobber (reg:CC FLAGS_REG))]
14630   "!TARGET_64BIT && TARGET_SUN_TLS"
14631   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14632         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14633   [(set_attr "type" "multi")
14634    (set_attr "length" "14")])
14636 (define_expand "tls_global_dynamic_32"
14637   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14638                    (unspec:SI
14639                     [(match_dup 2)
14640                      (match_operand:SI 1 "tls_symbolic_operand" "")
14641                      (match_dup 3)]
14642                     UNSPEC_TLS_GD))
14643               (clobber (match_scratch:SI 4 ""))
14644               (clobber (match_scratch:SI 5 ""))
14645               (clobber (reg:CC FLAGS_REG))])]
14646   ""
14648   if (flag_pic)
14649     operands[2] = pic_offset_table_rtx;
14650   else
14651     {
14652       operands[2] = gen_reg_rtx (Pmode);
14653       emit_insn (gen_set_got (operands[2]));
14654     }
14655   if (TARGET_GNU2_TLS)
14656     {
14657        emit_insn (gen_tls_dynamic_gnu2_32
14658                   (operands[0], operands[1], operands[2]));
14659        DONE;
14660     }
14661   operands[3] = ix86_tls_get_addr ();
14664 (define_insn "*tls_global_dynamic_64"
14665   [(set (match_operand:DI 0 "register_operand" "=a")
14666         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14667                  (match_operand:DI 3 "" "")))
14668    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14669               UNSPEC_TLS_GD)]
14670   "TARGET_64BIT"
14671   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14672   [(set_attr "type" "multi")
14673    (set_attr "length" "16")])
14675 (define_expand "tls_global_dynamic_64"
14676   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14677                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14678               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14679                          UNSPEC_TLS_GD)])]
14680   ""
14682   if (TARGET_GNU2_TLS)
14683     {
14684        emit_insn (gen_tls_dynamic_gnu2_64
14685                   (operands[0], operands[1]));
14686        DONE;
14687     }
14688   operands[2] = ix86_tls_get_addr ();
14691 (define_insn "*tls_local_dynamic_base_32_gnu"
14692   [(set (match_operand:SI 0 "register_operand" "=a")
14693         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14694                     (match_operand:SI 2 "call_insn_operand" "")]
14695                    UNSPEC_TLS_LD_BASE))
14696    (clobber (match_scratch:SI 3 "=d"))
14697    (clobber (match_scratch:SI 4 "=c"))
14698    (clobber (reg:CC FLAGS_REG))]
14699   "!TARGET_64BIT && TARGET_GNU_TLS"
14700   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14701   [(set_attr "type" "multi")
14702    (set_attr "length" "11")])
14704 (define_insn "*tls_local_dynamic_base_32_sun"
14705   [(set (match_operand:SI 0 "register_operand" "=a")
14706         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14707                     (match_operand:SI 2 "call_insn_operand" "")]
14708                    UNSPEC_TLS_LD_BASE))
14709    (clobber (match_scratch:SI 3 "=d"))
14710    (clobber (match_scratch:SI 4 "=c"))
14711    (clobber (reg:CC FLAGS_REG))]
14712   "!TARGET_64BIT && TARGET_SUN_TLS"
14713   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14714         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14715   [(set_attr "type" "multi")
14716    (set_attr "length" "13")])
14718 (define_expand "tls_local_dynamic_base_32"
14719   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14720                    (unspec:SI [(match_dup 1) (match_dup 2)]
14721                               UNSPEC_TLS_LD_BASE))
14722               (clobber (match_scratch:SI 3 ""))
14723               (clobber (match_scratch:SI 4 ""))
14724               (clobber (reg:CC FLAGS_REG))])]
14725   ""
14727   if (flag_pic)
14728     operands[1] = pic_offset_table_rtx;
14729   else
14730     {
14731       operands[1] = gen_reg_rtx (Pmode);
14732       emit_insn (gen_set_got (operands[1]));
14733     }
14734   if (TARGET_GNU2_TLS)
14735     {
14736        emit_insn (gen_tls_dynamic_gnu2_32
14737                   (operands[0], ix86_tls_module_base (), operands[1]));
14738        DONE;
14739     }
14740   operands[2] = ix86_tls_get_addr ();
14743 (define_insn "*tls_local_dynamic_base_64"
14744   [(set (match_operand:DI 0 "register_operand" "=a")
14745         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14746                  (match_operand:DI 2 "" "")))
14747    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14748   "TARGET_64BIT"
14749   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14750   [(set_attr "type" "multi")
14751    (set_attr "length" "12")])
14753 (define_expand "tls_local_dynamic_base_64"
14754   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14755                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14756               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14757   ""
14759   if (TARGET_GNU2_TLS)
14760     {
14761        emit_insn (gen_tls_dynamic_gnu2_64
14762                   (operands[0], ix86_tls_module_base ()));
14763        DONE;
14764     }
14765   operands[1] = ix86_tls_get_addr ();
14768 ;; Local dynamic of a single variable is a lose.  Show combine how
14769 ;; to convert that back to global dynamic.
14771 (define_insn_and_split "*tls_local_dynamic_32_once"
14772   [(set (match_operand:SI 0 "register_operand" "=a")
14773         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14774                              (match_operand:SI 2 "call_insn_operand" "")]
14775                             UNSPEC_TLS_LD_BASE)
14776                  (const:SI (unspec:SI
14777                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14778                             UNSPEC_DTPOFF))))
14779    (clobber (match_scratch:SI 4 "=d"))
14780    (clobber (match_scratch:SI 5 "=c"))
14781    (clobber (reg:CC FLAGS_REG))]
14782   ""
14783   "#"
14784   ""
14785   [(parallel [(set (match_dup 0)
14786                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14787                               UNSPEC_TLS_GD))
14788               (clobber (match_dup 4))
14789               (clobber (match_dup 5))
14790               (clobber (reg:CC FLAGS_REG))])]
14791   "")
14793 ;; Load and add the thread base pointer from %gs:0.
14795 (define_insn "*load_tp_si"
14796   [(set (match_operand:SI 0 "register_operand" "=r")
14797         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14798   "!TARGET_64BIT"
14799   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14800   [(set_attr "type" "imov")
14801    (set_attr "modrm" "0")
14802    (set_attr "length" "7")
14803    (set_attr "memory" "load")
14804    (set_attr "imm_disp" "false")])
14806 (define_insn "*add_tp_si"
14807   [(set (match_operand:SI 0 "register_operand" "=r")
14808         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14809                  (match_operand:SI 1 "register_operand" "0")))
14810    (clobber (reg:CC FLAGS_REG))]
14811   "!TARGET_64BIT"
14812   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14813   [(set_attr "type" "alu")
14814    (set_attr "modrm" "0")
14815    (set_attr "length" "7")
14816    (set_attr "memory" "load")
14817    (set_attr "imm_disp" "false")])
14819 (define_insn "*load_tp_di"
14820   [(set (match_operand:DI 0 "register_operand" "=r")
14821         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14822   "TARGET_64BIT"
14823   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14824   [(set_attr "type" "imov")
14825    (set_attr "modrm" "0")
14826    (set_attr "length" "7")
14827    (set_attr "memory" "load")
14828    (set_attr "imm_disp" "false")])
14830 (define_insn "*add_tp_di"
14831   [(set (match_operand:DI 0 "register_operand" "=r")
14832         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14833                  (match_operand:DI 1 "register_operand" "0")))
14834    (clobber (reg:CC FLAGS_REG))]
14835   "TARGET_64BIT"
14836   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14837   [(set_attr "type" "alu")
14838    (set_attr "modrm" "0")
14839    (set_attr "length" "7")
14840    (set_attr "memory" "load")
14841    (set_attr "imm_disp" "false")])
14843 ;; GNU2 TLS patterns can be split.
14845 (define_expand "tls_dynamic_gnu2_32"
14846   [(set (match_dup 3)
14847         (plus:SI (match_operand:SI 2 "register_operand" "")
14848                  (const:SI
14849                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14850                              UNSPEC_TLSDESC))))
14851    (parallel
14852     [(set (match_operand:SI 0 "register_operand" "")
14853           (unspec:SI [(match_dup 1) (match_dup 3)
14854                       (match_dup 2) (reg:SI SP_REG)]
14855                       UNSPEC_TLSDESC))
14856      (clobber (reg:CC FLAGS_REG))])]
14857   "!TARGET_64BIT && TARGET_GNU2_TLS"
14859   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14860   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14863 (define_insn "*tls_dynamic_lea_32"
14864   [(set (match_operand:SI 0 "register_operand" "=r")
14865         (plus:SI (match_operand:SI 1 "register_operand" "b")
14866                  (const:SI
14867                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14868                               UNSPEC_TLSDESC))))]
14869   "!TARGET_64BIT && TARGET_GNU2_TLS"
14870   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14871   [(set_attr "type" "lea")
14872    (set_attr "mode" "SI")
14873    (set_attr "length" "6")
14874    (set_attr "length_address" "4")])
14876 (define_insn "*tls_dynamic_call_32"
14877   [(set (match_operand:SI 0 "register_operand" "=a")
14878         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14879                     (match_operand:SI 2 "register_operand" "0")
14880                     ;; we have to make sure %ebx still points to the GOT
14881                     (match_operand:SI 3 "register_operand" "b")
14882                     (reg:SI SP_REG)]
14883                    UNSPEC_TLSDESC))
14884    (clobber (reg:CC FLAGS_REG))]
14885   "!TARGET_64BIT && TARGET_GNU2_TLS"
14886   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14887   [(set_attr "type" "call")
14888    (set_attr "length" "2")
14889    (set_attr "length_address" "0")])
14891 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14892   [(set (match_operand:SI 0 "register_operand" "=&a")
14893         (plus:SI
14894          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14895                      (match_operand:SI 4 "" "")
14896                      (match_operand:SI 2 "register_operand" "b")
14897                      (reg:SI SP_REG)]
14898                     UNSPEC_TLSDESC)
14899          (const:SI (unspec:SI
14900                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14901                     UNSPEC_DTPOFF))))
14902    (clobber (reg:CC FLAGS_REG))]
14903   "!TARGET_64BIT && TARGET_GNU2_TLS"
14904   "#"
14905   ""
14906   [(set (match_dup 0) (match_dup 5))]
14908   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14909   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14912 (define_expand "tls_dynamic_gnu2_64"
14913   [(set (match_dup 2)
14914         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14915                    UNSPEC_TLSDESC))
14916    (parallel
14917     [(set (match_operand:DI 0 "register_operand" "")
14918           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14919                      UNSPEC_TLSDESC))
14920      (clobber (reg:CC FLAGS_REG))])]
14921   "TARGET_64BIT && TARGET_GNU2_TLS"
14923   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14924   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14927 (define_insn "*tls_dynamic_lea_64"
14928   [(set (match_operand:DI 0 "register_operand" "=r")
14929         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14930                    UNSPEC_TLSDESC))]
14931   "TARGET_64BIT && TARGET_GNU2_TLS"
14932   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14933   [(set_attr "type" "lea")
14934    (set_attr "mode" "DI")
14935    (set_attr "length" "7")
14936    (set_attr "length_address" "4")])
14938 (define_insn "*tls_dynamic_call_64"
14939   [(set (match_operand:DI 0 "register_operand" "=a")
14940         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14941                     (match_operand:DI 2 "register_operand" "0")
14942                     (reg:DI SP_REG)]
14943                    UNSPEC_TLSDESC))
14944    (clobber (reg:CC FLAGS_REG))]
14945   "TARGET_64BIT && TARGET_GNU2_TLS"
14946   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14947   [(set_attr "type" "call")
14948    (set_attr "length" "2")
14949    (set_attr "length_address" "0")])
14951 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14952   [(set (match_operand:DI 0 "register_operand" "=&a")
14953         (plus:DI
14954          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14955                      (match_operand:DI 3 "" "")
14956                      (reg:DI SP_REG)]
14957                     UNSPEC_TLSDESC)
14958          (const:DI (unspec:DI
14959                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14960                     UNSPEC_DTPOFF))))
14961    (clobber (reg:CC FLAGS_REG))]
14962   "TARGET_64BIT && TARGET_GNU2_TLS"
14963   "#"
14964   ""
14965   [(set (match_dup 0) (match_dup 4))]
14967   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14968   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14973 ;; These patterns match the binary 387 instructions for addM3, subM3,
14974 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14975 ;; SFmode.  The first is the normal insn, the second the same insn but
14976 ;; with one operand a conversion, and the third the same insn but with
14977 ;; the other operand a conversion.  The conversion may be SFmode or
14978 ;; SImode if the target mode DFmode, but only SImode if the target mode
14979 ;; is SFmode.
14981 ;; Gcc is slightly more smart about handling normal two address instructions
14982 ;; so use special patterns for add and mull.
14984 (define_insn "*fop_sf_comm_mixed"
14985   [(set (match_operand:SF 0 "register_operand" "=f,x")
14986         (match_operator:SF 3 "binary_fp_operator"
14987                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14988                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14989   "TARGET_MIX_SSE_I387
14990    && COMMUTATIVE_ARITH_P (operands[3])
14991    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14992   "* return output_387_binary_op (insn, operands);"
14993   [(set (attr "type") 
14994         (if_then_else (eq_attr "alternative" "1")
14995            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14996               (const_string "ssemul")
14997               (const_string "sseadd"))
14998            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14999               (const_string "fmul")
15000               (const_string "fop"))))
15001    (set_attr "mode" "SF")])
15003 (define_insn "*fop_sf_comm_sse"
15004   [(set (match_operand:SF 0 "register_operand" "=x")
15005         (match_operator:SF 3 "binary_fp_operator"
15006                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15007                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15008   "TARGET_SSE_MATH
15009    && COMMUTATIVE_ARITH_P (operands[3])
15010    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15011   "* return output_387_binary_op (insn, operands);"
15012   [(set (attr "type") 
15013         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15014            (const_string "ssemul")
15015            (const_string "sseadd")))
15016    (set_attr "mode" "SF")])
15018 (define_insn "*fop_sf_comm_i387"
15019   [(set (match_operand:SF 0 "register_operand" "=f")
15020         (match_operator:SF 3 "binary_fp_operator"
15021                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15022                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15023   "TARGET_80387
15024    && COMMUTATIVE_ARITH_P (operands[3])
15025    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15026   "* return output_387_binary_op (insn, operands);"
15027   [(set (attr "type") 
15028         (if_then_else (match_operand:SF 3 "mult_operator" "") 
15029            (const_string "fmul")
15030            (const_string "fop")))
15031    (set_attr "mode" "SF")])
15033 (define_insn "*fop_sf_1_mixed"
15034   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15035         (match_operator:SF 3 "binary_fp_operator"
15036                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15037                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15038   "TARGET_MIX_SSE_I387
15039    && !COMMUTATIVE_ARITH_P (operands[3])
15040    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15041   "* return output_387_binary_op (insn, operands);"
15042   [(set (attr "type") 
15043         (cond [(and (eq_attr "alternative" "2")
15044                     (match_operand:SF 3 "mult_operator" ""))
15045                  (const_string "ssemul")
15046                (and (eq_attr "alternative" "2")
15047                     (match_operand:SF 3 "div_operator" ""))
15048                  (const_string "ssediv")
15049                (eq_attr "alternative" "2")
15050                  (const_string "sseadd")
15051                (match_operand:SF 3 "mult_operator" "") 
15052                  (const_string "fmul")
15053                (match_operand:SF 3 "div_operator" "") 
15054                  (const_string "fdiv")
15055               ]
15056               (const_string "fop")))
15057    (set_attr "mode" "SF")])
15059 (define_insn "*fop_sf_1_sse"
15060   [(set (match_operand:SF 0 "register_operand" "=x")
15061         (match_operator:SF 3 "binary_fp_operator"
15062                         [(match_operand:SF 1 "register_operand" "0")
15063                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15064   "TARGET_SSE_MATH
15065    && !COMMUTATIVE_ARITH_P (operands[3])"
15066   "* return output_387_binary_op (insn, operands);"
15067   [(set (attr "type") 
15068         (cond [(match_operand:SF 3 "mult_operator" "")
15069                  (const_string "ssemul")
15070                (match_operand:SF 3 "div_operator" "")
15071                  (const_string "ssediv")
15072               ]
15073               (const_string "sseadd")))
15074    (set_attr "mode" "SF")])
15076 ;; This pattern is not fully shadowed by the pattern above.
15077 (define_insn "*fop_sf_1_i387"
15078   [(set (match_operand:SF 0 "register_operand" "=f,f")
15079         (match_operator:SF 3 "binary_fp_operator"
15080                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15081                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15082   "TARGET_80387 && !TARGET_SSE_MATH
15083    && !COMMUTATIVE_ARITH_P (operands[3])
15084    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15085   "* return output_387_binary_op (insn, operands);"
15086   [(set (attr "type") 
15087         (cond [(match_operand:SF 3 "mult_operator" "") 
15088                  (const_string "fmul")
15089                (match_operand:SF 3 "div_operator" "") 
15090                  (const_string "fdiv")
15091               ]
15092               (const_string "fop")))
15093    (set_attr "mode" "SF")])
15095 ;; ??? Add SSE splitters for these!
15096 (define_insn "*fop_sf_2<mode>_i387"
15097   [(set (match_operand:SF 0 "register_operand" "=f,f")
15098         (match_operator:SF 3 "binary_fp_operator"
15099           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15100            (match_operand:SF 2 "register_operand" "0,0")]))]
15101   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15102   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15103   [(set (attr "type") 
15104         (cond [(match_operand:SF 3 "mult_operator" "") 
15105                  (const_string "fmul")
15106                (match_operand:SF 3 "div_operator" "") 
15107                  (const_string "fdiv")
15108               ]
15109               (const_string "fop")))
15110    (set_attr "fp_int_src" "true")
15111    (set_attr "mode" "<MODE>")])
15113 (define_insn "*fop_sf_3<mode>_i387"
15114   [(set (match_operand:SF 0 "register_operand" "=f,f")
15115         (match_operator:SF 3 "binary_fp_operator"
15116           [(match_operand:SF 1 "register_operand" "0,0")
15117            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15118   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15119   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15120   [(set (attr "type") 
15121         (cond [(match_operand:SF 3 "mult_operator" "") 
15122                  (const_string "fmul")
15123                (match_operand:SF 3 "div_operator" "") 
15124                  (const_string "fdiv")
15125               ]
15126               (const_string "fop")))
15127    (set_attr "fp_int_src" "true")
15128    (set_attr "mode" "<MODE>")])
15130 (define_insn "*fop_df_comm_mixed"
15131   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15132         (match_operator:DF 3 "binary_fp_operator"
15133                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15134                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15135   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15136    && COMMUTATIVE_ARITH_P (operands[3])
15137    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15138   "* return output_387_binary_op (insn, operands);"
15139   [(set (attr "type") 
15140         (if_then_else (eq_attr "alternative" "1")
15141            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15142               (const_string "ssemul")
15143               (const_string "sseadd"))
15144            (if_then_else (match_operand:DF 3 "mult_operator" "") 
15145               (const_string "fmul")
15146               (const_string "fop"))))
15147    (set_attr "mode" "DF")])
15149 (define_insn "*fop_df_comm_sse"
15150   [(set (match_operand:DF 0 "register_operand" "=Y")
15151         (match_operator:DF 3 "binary_fp_operator"
15152                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15153                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15154   "TARGET_SSE2 && TARGET_SSE_MATH
15155    && COMMUTATIVE_ARITH_P (operands[3])
15156    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15157   "* return output_387_binary_op (insn, operands);"
15158   [(set (attr "type") 
15159         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15160            (const_string "ssemul")
15161            (const_string "sseadd")))
15162    (set_attr "mode" "DF")])
15164 (define_insn "*fop_df_comm_i387"
15165   [(set (match_operand:DF 0 "register_operand" "=f")
15166         (match_operator:DF 3 "binary_fp_operator"
15167                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15168                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15169   "TARGET_80387
15170    && COMMUTATIVE_ARITH_P (operands[3])
15171    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15172   "* return output_387_binary_op (insn, operands);"
15173   [(set (attr "type") 
15174         (if_then_else (match_operand:DF 3 "mult_operator" "") 
15175            (const_string "fmul")
15176            (const_string "fop")))
15177    (set_attr "mode" "DF")])
15179 (define_insn "*fop_df_1_mixed"
15180   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15181         (match_operator:DF 3 "binary_fp_operator"
15182                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15183                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15184   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15185    && !COMMUTATIVE_ARITH_P (operands[3])
15186    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15187   "* return output_387_binary_op (insn, operands);"
15188   [(set (attr "type") 
15189         (cond [(and (eq_attr "alternative" "2")
15190                     (match_operand:DF 3 "mult_operator" ""))
15191                  (const_string "ssemul")
15192                (and (eq_attr "alternative" "2")
15193                     (match_operand:DF 3 "div_operator" ""))
15194                  (const_string "ssediv")
15195                (eq_attr "alternative" "2")
15196                  (const_string "sseadd")
15197                (match_operand:DF 3 "mult_operator" "") 
15198                  (const_string "fmul")
15199                (match_operand:DF 3 "div_operator" "") 
15200                  (const_string "fdiv")
15201               ]
15202               (const_string "fop")))
15203    (set_attr "mode" "DF")])
15205 (define_insn "*fop_df_1_sse"
15206   [(set (match_operand:DF 0 "register_operand" "=Y")
15207         (match_operator:DF 3 "binary_fp_operator"
15208                         [(match_operand:DF 1 "register_operand" "0")
15209                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15210   "TARGET_SSE2 && TARGET_SSE_MATH
15211    && !COMMUTATIVE_ARITH_P (operands[3])"
15212   "* return output_387_binary_op (insn, operands);"
15213   [(set_attr "mode" "DF")
15214    (set (attr "type") 
15215         (cond [(match_operand:DF 3 "mult_operator" "")
15216                  (const_string "ssemul")
15217                (match_operand:DF 3 "div_operator" "")
15218                  (const_string "ssediv")
15219               ]
15220               (const_string "sseadd")))])
15222 ;; This pattern is not fully shadowed by the pattern above.
15223 (define_insn "*fop_df_1_i387"
15224   [(set (match_operand:DF 0 "register_operand" "=f,f")
15225         (match_operator:DF 3 "binary_fp_operator"
15226                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15227                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15228   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15229    && !COMMUTATIVE_ARITH_P (operands[3])
15230    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15231   "* return output_387_binary_op (insn, operands);"
15232   [(set (attr "type") 
15233         (cond [(match_operand:DF 3 "mult_operator" "") 
15234                  (const_string "fmul")
15235                (match_operand:DF 3 "div_operator" "")
15236                  (const_string "fdiv")
15237               ]
15238               (const_string "fop")))
15239    (set_attr "mode" "DF")])
15241 ;; ??? Add SSE splitters for these!
15242 (define_insn "*fop_df_2<mode>_i387"
15243   [(set (match_operand:DF 0 "register_operand" "=f,f")
15244         (match_operator:DF 3 "binary_fp_operator"
15245            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15246             (match_operand:DF 2 "register_operand" "0,0")]))]
15247   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15248    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15249   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15250   [(set (attr "type") 
15251         (cond [(match_operand:DF 3 "mult_operator" "") 
15252                  (const_string "fmul")
15253                (match_operand:DF 3 "div_operator" "") 
15254                  (const_string "fdiv")
15255               ]
15256               (const_string "fop")))
15257    (set_attr "fp_int_src" "true")
15258    (set_attr "mode" "<MODE>")])
15260 (define_insn "*fop_df_3<mode>_i387"
15261   [(set (match_operand:DF 0 "register_operand" "=f,f")
15262         (match_operator:DF 3 "binary_fp_operator"
15263            [(match_operand:DF 1 "register_operand" "0,0")
15264             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15265   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15266    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15267   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15268   [(set (attr "type") 
15269         (cond [(match_operand:DF 3 "mult_operator" "") 
15270                  (const_string "fmul")
15271                (match_operand:DF 3 "div_operator" "") 
15272                  (const_string "fdiv")
15273               ]
15274               (const_string "fop")))
15275    (set_attr "fp_int_src" "true")
15276    (set_attr "mode" "<MODE>")])
15278 (define_insn "*fop_df_4_i387"
15279   [(set (match_operand:DF 0 "register_operand" "=f,f")
15280         (match_operator:DF 3 "binary_fp_operator"
15281            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15282             (match_operand:DF 2 "register_operand" "0,f")]))]
15283   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15284    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15285   "* return output_387_binary_op (insn, operands);"
15286   [(set (attr "type") 
15287         (cond [(match_operand:DF 3 "mult_operator" "") 
15288                  (const_string "fmul")
15289                (match_operand:DF 3 "div_operator" "") 
15290                  (const_string "fdiv")
15291               ]
15292               (const_string "fop")))
15293    (set_attr "mode" "SF")])
15295 (define_insn "*fop_df_5_i387"
15296   [(set (match_operand:DF 0 "register_operand" "=f,f")
15297         (match_operator:DF 3 "binary_fp_operator"
15298           [(match_operand:DF 1 "register_operand" "0,f")
15299            (float_extend:DF
15300             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15301   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15302   "* return output_387_binary_op (insn, operands);"
15303   [(set (attr "type") 
15304         (cond [(match_operand:DF 3 "mult_operator" "") 
15305                  (const_string "fmul")
15306                (match_operand:DF 3 "div_operator" "") 
15307                  (const_string "fdiv")
15308               ]
15309               (const_string "fop")))
15310    (set_attr "mode" "SF")])
15312 (define_insn "*fop_df_6_i387"
15313   [(set (match_operand:DF 0 "register_operand" "=f,f")
15314         (match_operator:DF 3 "binary_fp_operator"
15315           [(float_extend:DF
15316             (match_operand:SF 1 "register_operand" "0,f"))
15317            (float_extend:DF
15318             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15319   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15320   "* return output_387_binary_op (insn, operands);"
15321   [(set (attr "type") 
15322         (cond [(match_operand:DF 3 "mult_operator" "") 
15323                  (const_string "fmul")
15324                (match_operand:DF 3 "div_operator" "") 
15325                  (const_string "fdiv")
15326               ]
15327               (const_string "fop")))
15328    (set_attr "mode" "SF")])
15330 (define_insn "*fop_xf_comm_i387"
15331   [(set (match_operand:XF 0 "register_operand" "=f")
15332         (match_operator:XF 3 "binary_fp_operator"
15333                         [(match_operand:XF 1 "register_operand" "%0")
15334                          (match_operand:XF 2 "register_operand" "f")]))]
15335   "TARGET_80387
15336    && COMMUTATIVE_ARITH_P (operands[3])"
15337   "* return output_387_binary_op (insn, operands);"
15338   [(set (attr "type") 
15339         (if_then_else (match_operand:XF 3 "mult_operator" "") 
15340            (const_string "fmul")
15341            (const_string "fop")))
15342    (set_attr "mode" "XF")])
15344 (define_insn "*fop_xf_1_i387"
15345   [(set (match_operand:XF 0 "register_operand" "=f,f")
15346         (match_operator:XF 3 "binary_fp_operator"
15347                         [(match_operand:XF 1 "register_operand" "0,f")
15348                          (match_operand:XF 2 "register_operand" "f,0")]))]
15349   "TARGET_80387
15350    && !COMMUTATIVE_ARITH_P (operands[3])"
15351   "* return output_387_binary_op (insn, operands);"
15352   [(set (attr "type") 
15353         (cond [(match_operand:XF 3 "mult_operator" "") 
15354                  (const_string "fmul")
15355                (match_operand:XF 3 "div_operator" "") 
15356                  (const_string "fdiv")
15357               ]
15358               (const_string "fop")))
15359    (set_attr "mode" "XF")])
15361 (define_insn "*fop_xf_2<mode>_i387"
15362   [(set (match_operand:XF 0 "register_operand" "=f,f")
15363         (match_operator:XF 3 "binary_fp_operator"
15364            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15365             (match_operand:XF 2 "register_operand" "0,0")]))]
15366   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15367   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15368   [(set (attr "type") 
15369         (cond [(match_operand:XF 3 "mult_operator" "") 
15370                  (const_string "fmul")
15371                (match_operand:XF 3 "div_operator" "") 
15372                  (const_string "fdiv")
15373               ]
15374               (const_string "fop")))
15375    (set_attr "fp_int_src" "true")
15376    (set_attr "mode" "<MODE>")])
15378 (define_insn "*fop_xf_3<mode>_i387"
15379   [(set (match_operand:XF 0 "register_operand" "=f,f")
15380         (match_operator:XF 3 "binary_fp_operator"
15381           [(match_operand:XF 1 "register_operand" "0,0")
15382            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15383   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15384   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15385   [(set (attr "type") 
15386         (cond [(match_operand:XF 3 "mult_operator" "") 
15387                  (const_string "fmul")
15388                (match_operand:XF 3 "div_operator" "") 
15389                  (const_string "fdiv")
15390               ]
15391               (const_string "fop")))
15392    (set_attr "fp_int_src" "true")
15393    (set_attr "mode" "<MODE>")])
15395 (define_insn "*fop_xf_4_i387"
15396   [(set (match_operand:XF 0 "register_operand" "=f,f")
15397         (match_operator:XF 3 "binary_fp_operator"
15398            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15399             (match_operand:XF 2 "register_operand" "0,f")]))]
15400   "TARGET_80387"
15401   "* return output_387_binary_op (insn, operands);"
15402   [(set (attr "type") 
15403         (cond [(match_operand:XF 3 "mult_operator" "") 
15404                  (const_string "fmul")
15405                (match_operand:XF 3 "div_operator" "") 
15406                  (const_string "fdiv")
15407               ]
15408               (const_string "fop")))
15409    (set_attr "mode" "SF")])
15411 (define_insn "*fop_xf_5_i387"
15412   [(set (match_operand:XF 0 "register_operand" "=f,f")
15413         (match_operator:XF 3 "binary_fp_operator"
15414           [(match_operand:XF 1 "register_operand" "0,f")
15415            (float_extend:XF
15416             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15417   "TARGET_80387"
15418   "* return output_387_binary_op (insn, operands);"
15419   [(set (attr "type") 
15420         (cond [(match_operand:XF 3 "mult_operator" "") 
15421                  (const_string "fmul")
15422                (match_operand:XF 3 "div_operator" "") 
15423                  (const_string "fdiv")
15424               ]
15425               (const_string "fop")))
15426    (set_attr "mode" "SF")])
15428 (define_insn "*fop_xf_6_i387"
15429   [(set (match_operand:XF 0 "register_operand" "=f,f")
15430         (match_operator:XF 3 "binary_fp_operator"
15431           [(float_extend:XF
15432             (match_operand 1 "register_operand" "0,f"))
15433            (float_extend:XF
15434             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15435   "TARGET_80387"
15436   "* return output_387_binary_op (insn, operands);"
15437   [(set (attr "type") 
15438         (cond [(match_operand:XF 3 "mult_operator" "") 
15439                  (const_string "fmul")
15440                (match_operand:XF 3 "div_operator" "") 
15441                  (const_string "fdiv")
15442               ]
15443               (const_string "fop")))
15444    (set_attr "mode" "SF")])
15446 (define_split
15447   [(set (match_operand 0 "register_operand" "")
15448         (match_operator 3 "binary_fp_operator"
15449            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15450             (match_operand 2 "register_operand" "")]))]
15451   "TARGET_80387 && reload_completed
15452    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15453   [(const_int 0)]
15455   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15456   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15457   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15458                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15459                                           GET_MODE (operands[3]),
15460                                           operands[4],
15461                                           operands[2])));
15462   ix86_free_from_memory (GET_MODE (operands[1]));
15463   DONE;
15466 (define_split
15467   [(set (match_operand 0 "register_operand" "")
15468         (match_operator 3 "binary_fp_operator"
15469            [(match_operand 1 "register_operand" "")
15470             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15471   "TARGET_80387 && reload_completed
15472    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15473   [(const_int 0)]
15475   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15476   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15477   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15478                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15479                                           GET_MODE (operands[3]),
15480                                           operands[1],
15481                                           operands[4])));
15482   ix86_free_from_memory (GET_MODE (operands[2]));
15483   DONE;
15486 ;; FPU special functions.
15488 (define_expand "sqrtsf2"
15489   [(set (match_operand:SF 0 "register_operand" "")
15490         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15491   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15493   if (!TARGET_SSE_MATH)
15494     operands[1] = force_reg (SFmode, operands[1]);
15497 (define_insn "*sqrtsf2_mixed"
15498   [(set (match_operand:SF 0 "register_operand" "=f,x")
15499         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15500   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15501   "@
15502    fsqrt
15503    sqrtss\t{%1, %0|%0, %1}"
15504   [(set_attr "type" "fpspc,sse")
15505    (set_attr "mode" "SF,SF")
15506    (set_attr "athlon_decode" "direct,*")])
15508 (define_insn "*sqrtsf2_sse"
15509   [(set (match_operand:SF 0 "register_operand" "=x")
15510         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15511   "TARGET_SSE_MATH"
15512   "sqrtss\t{%1, %0|%0, %1}"
15513   [(set_attr "type" "sse")
15514    (set_attr "mode" "SF")
15515    (set_attr "athlon_decode" "*")])
15517 (define_insn "*sqrtsf2_i387"
15518   [(set (match_operand:SF 0 "register_operand" "=f")
15519         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15520   "TARGET_USE_FANCY_MATH_387"
15521   "fsqrt"
15522   [(set_attr "type" "fpspc")
15523    (set_attr "mode" "SF")
15524    (set_attr "athlon_decode" "direct")])
15526 (define_expand "sqrtdf2"
15527   [(set (match_operand:DF 0 "register_operand" "")
15528         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15529   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15531   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15532     operands[1] = force_reg (DFmode, operands[1]);
15535 (define_insn "*sqrtdf2_mixed"
15536   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15537         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15538   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15539   "@
15540    fsqrt
15541    sqrtsd\t{%1, %0|%0, %1}"
15542   [(set_attr "type" "fpspc,sse")
15543    (set_attr "mode" "DF,DF")
15544    (set_attr "athlon_decode" "direct,*")])
15546 (define_insn "*sqrtdf2_sse"
15547   [(set (match_operand:DF 0 "register_operand" "=Y")
15548         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15549   "TARGET_SSE2 && TARGET_SSE_MATH"
15550   "sqrtsd\t{%1, %0|%0, %1}"
15551   [(set_attr "type" "sse")
15552    (set_attr "mode" "DF")
15553    (set_attr "athlon_decode" "*")])
15555 (define_insn "*sqrtdf2_i387"
15556   [(set (match_operand:DF 0 "register_operand" "=f")
15557         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15558   "TARGET_USE_FANCY_MATH_387"
15559   "fsqrt"
15560   [(set_attr "type" "fpspc")
15561    (set_attr "mode" "DF")
15562    (set_attr "athlon_decode" "direct")])
15564 (define_insn "*sqrtextendsfdf2_i387"
15565   [(set (match_operand:DF 0 "register_operand" "=f")
15566         (sqrt:DF (float_extend:DF
15567                   (match_operand:SF 1 "register_operand" "0"))))]
15568   "TARGET_USE_FANCY_MATH_387
15569    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15570   "fsqrt"
15571   [(set_attr "type" "fpspc")
15572    (set_attr "mode" "DF")
15573    (set_attr "athlon_decode" "direct")])
15575 (define_insn "sqrtxf2"
15576   [(set (match_operand:XF 0 "register_operand" "=f")
15577         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15578   "TARGET_USE_FANCY_MATH_387"
15579   "fsqrt"
15580   [(set_attr "type" "fpspc")
15581    (set_attr "mode" "XF")
15582    (set_attr "athlon_decode" "direct")])
15584 (define_insn "*sqrtextendsfxf2_i387"
15585   [(set (match_operand:XF 0 "register_operand" "=f")
15586         (sqrt:XF (float_extend:XF
15587                   (match_operand:SF 1 "register_operand" "0"))))]
15588   "TARGET_USE_FANCY_MATH_387"
15589   "fsqrt"
15590   [(set_attr "type" "fpspc")
15591    (set_attr "mode" "XF")
15592    (set_attr "athlon_decode" "direct")])
15594 (define_insn "*sqrtextenddfxf2_i387"
15595   [(set (match_operand:XF 0 "register_operand" "=f")
15596         (sqrt:XF (float_extend:XF
15597                   (match_operand:DF 1 "register_operand" "0"))))]
15598   "TARGET_USE_FANCY_MATH_387"
15599   "fsqrt"
15600   [(set_attr "type" "fpspc")
15601    (set_attr "mode" "XF")
15602    (set_attr "athlon_decode" "direct")])
15604 (define_insn "fpremxf4"
15605   [(set (match_operand:XF 0 "register_operand" "=f")
15606         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15607                     (match_operand:XF 3 "register_operand" "1")]
15608                    UNSPEC_FPREM_F))
15609    (set (match_operand:XF 1 "register_operand" "=u")
15610         (unspec:XF [(match_dup 2) (match_dup 3)]
15611                    UNSPEC_FPREM_U))
15612    (set (reg:CCFP FPSR_REG)
15613         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15614   "TARGET_USE_FANCY_MATH_387"
15615   "fprem"
15616   [(set_attr "type" "fpspc")
15617    (set_attr "mode" "XF")])
15619 (define_expand "fmodsf3"
15620   [(use (match_operand:SF 0 "register_operand" ""))
15621    (use (match_operand:SF 1 "register_operand" ""))
15622    (use (match_operand:SF 2 "register_operand" ""))]
15623   "TARGET_USE_FANCY_MATH_387
15624    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15626   rtx label = gen_label_rtx ();
15628   rtx op1 = gen_reg_rtx (XFmode);
15629   rtx op2 = gen_reg_rtx (XFmode);
15631   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15632   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15634   emit_label (label);
15636   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15637   ix86_emit_fp_unordered_jump (label);
15639   emit_insn (gen_truncxfsf2 (operands[0], op1));
15640   DONE;
15643 (define_expand "fmoddf3"
15644   [(use (match_operand:DF 0 "register_operand" ""))
15645    (use (match_operand:DF 1 "register_operand" ""))
15646    (use (match_operand:DF 2 "register_operand" ""))]
15647   "TARGET_USE_FANCY_MATH_387
15648    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15650   rtx label = gen_label_rtx ();
15652   rtx op1 = gen_reg_rtx (XFmode);
15653   rtx op2 = gen_reg_rtx (XFmode);
15655   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15656   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15658   emit_label (label);
15660   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15661   ix86_emit_fp_unordered_jump (label);
15663   emit_insn (gen_truncxfdf2 (operands[0], op1));
15664   DONE;
15667 (define_expand "fmodxf3"
15668   [(use (match_operand:XF 0 "register_operand" ""))
15669    (use (match_operand:XF 1 "register_operand" ""))
15670    (use (match_operand:XF 2 "register_operand" ""))]
15671   "TARGET_USE_FANCY_MATH_387"
15673   rtx label = gen_label_rtx ();
15675   emit_label (label);
15677   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15678                            operands[1], operands[2]));
15679   ix86_emit_fp_unordered_jump (label);
15681   emit_move_insn (operands[0], operands[1]);
15682   DONE;
15685 (define_insn "fprem1xf4"
15686   [(set (match_operand:XF 0 "register_operand" "=f")
15687         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15688                     (match_operand:XF 3 "register_operand" "1")]
15689                    UNSPEC_FPREM1_F))
15690    (set (match_operand:XF 1 "register_operand" "=u")
15691         (unspec:XF [(match_dup 2) (match_dup 3)]
15692                    UNSPEC_FPREM1_U))
15693    (set (reg:CCFP FPSR_REG)
15694         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15695   "TARGET_USE_FANCY_MATH_387"
15696   "fprem1"
15697   [(set_attr "type" "fpspc")
15698    (set_attr "mode" "XF")])
15700 (define_expand "remaindersf3"
15701   [(use (match_operand:SF 0 "register_operand" ""))
15702    (use (match_operand:SF 1 "register_operand" ""))
15703    (use (match_operand:SF 2 "register_operand" ""))]
15704   "TARGET_USE_FANCY_MATH_387
15705    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15707   rtx label = gen_label_rtx ();
15709   rtx op1 = gen_reg_rtx (XFmode);
15710   rtx op2 = gen_reg_rtx (XFmode);
15712   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15713   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15715   emit_label (label);
15717   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15718   ix86_emit_fp_unordered_jump (label);
15720   emit_insn (gen_truncxfsf2 (operands[0], op1));
15721   DONE;
15724 (define_expand "remainderdf3"
15725   [(use (match_operand:DF 0 "register_operand" ""))
15726    (use (match_operand:DF 1 "register_operand" ""))
15727    (use (match_operand:DF 2 "register_operand" ""))]
15728   "TARGET_USE_FANCY_MATH_387
15729    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15731   rtx label = gen_label_rtx ();
15733   rtx op1 = gen_reg_rtx (XFmode);
15734   rtx op2 = gen_reg_rtx (XFmode);
15736   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15737   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15739   emit_label (label);
15741   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15742   ix86_emit_fp_unordered_jump (label);
15744   emit_insn (gen_truncxfdf2 (operands[0], op1));
15745   DONE;
15748 (define_expand "remainderxf3"
15749   [(use (match_operand:XF 0 "register_operand" ""))
15750    (use (match_operand:XF 1 "register_operand" ""))
15751    (use (match_operand:XF 2 "register_operand" ""))]
15752   "TARGET_USE_FANCY_MATH_387"
15754   rtx label = gen_label_rtx ();
15756   emit_label (label);
15758   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15759                             operands[1], operands[2]));
15760   ix86_emit_fp_unordered_jump (label);
15762   emit_move_insn (operands[0], operands[1]);
15763   DONE;
15766 (define_insn "*sindf2"
15767   [(set (match_operand:DF 0 "register_operand" "=f")
15768         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15769   "TARGET_USE_FANCY_MATH_387
15770    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15771    && flag_unsafe_math_optimizations"
15772   "fsin"
15773   [(set_attr "type" "fpspc")
15774    (set_attr "mode" "DF")])
15776 (define_insn "*sinsf2"
15777   [(set (match_operand:SF 0 "register_operand" "=f")
15778         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15779   "TARGET_USE_FANCY_MATH_387
15780    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15781    && flag_unsafe_math_optimizations"
15782   "fsin"
15783   [(set_attr "type" "fpspc")
15784    (set_attr "mode" "SF")])
15786 (define_insn "*sinextendsfdf2"
15787   [(set (match_operand:DF 0 "register_operand" "=f")
15788         (unspec:DF [(float_extend:DF
15789                      (match_operand:SF 1 "register_operand" "0"))]
15790                    UNSPEC_SIN))]
15791   "TARGET_USE_FANCY_MATH_387
15792    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15793    && flag_unsafe_math_optimizations"
15794   "fsin"
15795   [(set_attr "type" "fpspc")
15796    (set_attr "mode" "DF")])
15798 (define_insn "*sinxf2"
15799   [(set (match_operand:XF 0 "register_operand" "=f")
15800         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15801   "TARGET_USE_FANCY_MATH_387
15802    && flag_unsafe_math_optimizations"
15803   "fsin"
15804   [(set_attr "type" "fpspc")
15805    (set_attr "mode" "XF")])
15807 (define_insn "*cosdf2"
15808   [(set (match_operand:DF 0 "register_operand" "=f")
15809         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15810   "TARGET_USE_FANCY_MATH_387
15811    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15812    && flag_unsafe_math_optimizations"
15813   "fcos"
15814   [(set_attr "type" "fpspc")
15815    (set_attr "mode" "DF")])
15817 (define_insn "*cossf2"
15818   [(set (match_operand:SF 0 "register_operand" "=f")
15819         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15820   "TARGET_USE_FANCY_MATH_387
15821    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15822    && flag_unsafe_math_optimizations"
15823   "fcos"
15824   [(set_attr "type" "fpspc")
15825    (set_attr "mode" "SF")])
15827 (define_insn "*cosextendsfdf2"
15828   [(set (match_operand:DF 0 "register_operand" "=f")
15829         (unspec:DF [(float_extend:DF
15830                      (match_operand:SF 1 "register_operand" "0"))]
15831                    UNSPEC_COS))]
15832   "TARGET_USE_FANCY_MATH_387
15833    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15834    && flag_unsafe_math_optimizations"
15835   "fcos"
15836   [(set_attr "type" "fpspc")
15837    (set_attr "mode" "DF")])
15839 (define_insn "*cosxf2"
15840   [(set (match_operand:XF 0 "register_operand" "=f")
15841         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15842   "TARGET_USE_FANCY_MATH_387
15843    && flag_unsafe_math_optimizations"
15844   "fcos"
15845   [(set_attr "type" "fpspc")
15846    (set_attr "mode" "XF")])
15848 ;; With sincos pattern defined, sin and cos builtin function will be
15849 ;; expanded to sincos pattern with one of its outputs left unused. 
15850 ;; Cse pass  will detected, if two sincos patterns can be combined,
15851 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15852 ;; depending on the unused output.
15854 (define_insn "sincosdf3"
15855   [(set (match_operand:DF 0 "register_operand" "=f")
15856         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15857                    UNSPEC_SINCOS_COS))
15858    (set (match_operand:DF 1 "register_operand" "=u")
15859         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15860   "TARGET_USE_FANCY_MATH_387
15861    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15862    && flag_unsafe_math_optimizations"
15863   "fsincos"
15864   [(set_attr "type" "fpspc")
15865    (set_attr "mode" "DF")])
15867 (define_split
15868   [(set (match_operand:DF 0 "register_operand" "")
15869         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15870                    UNSPEC_SINCOS_COS))
15871    (set (match_operand:DF 1 "register_operand" "")
15872         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15873   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15874    && !reload_completed && !reload_in_progress"
15875   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15876   "")
15878 (define_split
15879   [(set (match_operand:DF 0 "register_operand" "")
15880         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15881                    UNSPEC_SINCOS_COS))
15882    (set (match_operand:DF 1 "register_operand" "")
15883         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15884   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15885    && !reload_completed && !reload_in_progress"
15886   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15887   "")
15889 (define_insn "sincossf3"
15890   [(set (match_operand:SF 0 "register_operand" "=f")
15891         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15892                    UNSPEC_SINCOS_COS))
15893    (set (match_operand:SF 1 "register_operand" "=u")
15894         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15895   "TARGET_USE_FANCY_MATH_387
15896    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15897    && flag_unsafe_math_optimizations"
15898   "fsincos"
15899   [(set_attr "type" "fpspc")
15900    (set_attr "mode" "SF")])
15902 (define_split
15903   [(set (match_operand:SF 0 "register_operand" "")
15904         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15905                    UNSPEC_SINCOS_COS))
15906    (set (match_operand:SF 1 "register_operand" "")
15907         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15908   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15909    && !reload_completed && !reload_in_progress"
15910   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15911   "")
15913 (define_split
15914   [(set (match_operand:SF 0 "register_operand" "")
15915         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15916                    UNSPEC_SINCOS_COS))
15917    (set (match_operand:SF 1 "register_operand" "")
15918         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15919   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15920    && !reload_completed && !reload_in_progress"
15921   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15922   "")
15924 (define_insn "*sincosextendsfdf3"
15925   [(set (match_operand:DF 0 "register_operand" "=f")
15926         (unspec:DF [(float_extend:DF
15927                      (match_operand:SF 2 "register_operand" "0"))]
15928                    UNSPEC_SINCOS_COS))
15929    (set (match_operand:DF 1 "register_operand" "=u")
15930         (unspec:DF [(float_extend:DF
15931                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15932   "TARGET_USE_FANCY_MATH_387
15933    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15934    && flag_unsafe_math_optimizations"
15935   "fsincos"
15936   [(set_attr "type" "fpspc")
15937    (set_attr "mode" "DF")])
15939 (define_split
15940   [(set (match_operand:DF 0 "register_operand" "")
15941         (unspec:DF [(float_extend:DF
15942                      (match_operand:SF 2 "register_operand" ""))]
15943                    UNSPEC_SINCOS_COS))
15944    (set (match_operand:DF 1 "register_operand" "")
15945         (unspec:DF [(float_extend:DF
15946                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15947   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15948    && !reload_completed && !reload_in_progress"
15949   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15950                                    (match_dup 2))] UNSPEC_SIN))]
15951   "")
15953 (define_split
15954   [(set (match_operand:DF 0 "register_operand" "")
15955         (unspec:DF [(float_extend:DF
15956                      (match_operand:SF 2 "register_operand" ""))]
15957                    UNSPEC_SINCOS_COS))
15958    (set (match_operand:DF 1 "register_operand" "")
15959         (unspec:DF [(float_extend:DF
15960                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15961   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15962    && !reload_completed && !reload_in_progress"
15963   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15964                                    (match_dup 2))] UNSPEC_COS))]
15965   "")
15967 (define_insn "sincosxf3"
15968   [(set (match_operand:XF 0 "register_operand" "=f")
15969         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15970                    UNSPEC_SINCOS_COS))
15971    (set (match_operand:XF 1 "register_operand" "=u")
15972         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15973   "TARGET_USE_FANCY_MATH_387
15974    && flag_unsafe_math_optimizations"
15975   "fsincos"
15976   [(set_attr "type" "fpspc")
15977    (set_attr "mode" "XF")])
15979 (define_split
15980   [(set (match_operand:XF 0 "register_operand" "")
15981         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15982                    UNSPEC_SINCOS_COS))
15983    (set (match_operand:XF 1 "register_operand" "")
15984         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15985   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15986    && !reload_completed && !reload_in_progress"
15987   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15988   "")
15990 (define_split
15991   [(set (match_operand:XF 0 "register_operand" "")
15992         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15993                    UNSPEC_SINCOS_COS))
15994    (set (match_operand:XF 1 "register_operand" "")
15995         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15996   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15997    && !reload_completed && !reload_in_progress"
15998   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15999   "")
16001 (define_insn "*tandf3_1"
16002   [(set (match_operand:DF 0 "register_operand" "=f")
16003         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16004                    UNSPEC_TAN_ONE))
16005    (set (match_operand:DF 1 "register_operand" "=u")
16006         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16007   "TARGET_USE_FANCY_MATH_387
16008    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16009    && flag_unsafe_math_optimizations"
16010   "fptan"
16011   [(set_attr "type" "fpspc")
16012    (set_attr "mode" "DF")])
16014 ;; optimize sequence: fptan
16015 ;;                    fstp    %st(0)
16016 ;;                    fld1
16017 ;; into fptan insn.
16019 (define_peephole2
16020   [(parallel[(set (match_operand:DF 0 "register_operand" "")
16021                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16022                              UNSPEC_TAN_ONE))
16023              (set (match_operand:DF 1 "register_operand" "")
16024                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16025    (set (match_dup 0)
16026         (match_operand:DF 3 "immediate_operand" ""))]
16027   "standard_80387_constant_p (operands[3]) == 2"
16028   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16029              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16030   "")
16032 (define_expand "tandf2"
16033   [(parallel [(set (match_dup 2)
16034                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16035                               UNSPEC_TAN_ONE))
16036               (set (match_operand:DF 0 "register_operand" "")
16037                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16038   "TARGET_USE_FANCY_MATH_387
16039    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16040    && flag_unsafe_math_optimizations"
16042   operands[2] = gen_reg_rtx (DFmode);
16045 (define_insn "*tansf3_1"
16046   [(set (match_operand:SF 0 "register_operand" "=f")
16047         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16048                    UNSPEC_TAN_ONE))
16049    (set (match_operand:SF 1 "register_operand" "=u")
16050         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16051   "TARGET_USE_FANCY_MATH_387
16052    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16053    && flag_unsafe_math_optimizations"
16054   "fptan"
16055   [(set_attr "type" "fpspc")
16056    (set_attr "mode" "SF")])
16058 ;; optimize sequence: fptan
16059 ;;                    fstp    %st(0)
16060 ;;                    fld1
16061 ;; into fptan insn.
16063 (define_peephole2
16064   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16065                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16066                              UNSPEC_TAN_ONE))
16067              (set (match_operand:SF 1 "register_operand" "")
16068                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16069    (set (match_dup 0)
16070         (match_operand:SF 3 "immediate_operand" ""))]
16071   "standard_80387_constant_p (operands[3]) == 2"
16072   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16073              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16074   "")
16076 (define_expand "tansf2"
16077   [(parallel [(set (match_dup 2)
16078                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16079                               UNSPEC_TAN_ONE))
16080               (set (match_operand:SF 0 "register_operand" "")
16081                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16082   "TARGET_USE_FANCY_MATH_387
16083    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16084    && flag_unsafe_math_optimizations"
16086   operands[2] = gen_reg_rtx (SFmode);
16089 (define_insn "*tanxf3_1"
16090   [(set (match_operand:XF 0 "register_operand" "=f")
16091         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16092                    UNSPEC_TAN_ONE))
16093    (set (match_operand:XF 1 "register_operand" "=u")
16094         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16095   "TARGET_USE_FANCY_MATH_387
16096    && flag_unsafe_math_optimizations"
16097   "fptan"
16098   [(set_attr "type" "fpspc")
16099    (set_attr "mode" "XF")])
16101 ;; optimize sequence: fptan
16102 ;;                    fstp    %st(0)
16103 ;;                    fld1
16104 ;; into fptan insn.
16106 (define_peephole2
16107   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16108                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16109                              UNSPEC_TAN_ONE))
16110              (set (match_operand:XF 1 "register_operand" "")
16111                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16112    (set (match_dup 0)
16113         (match_operand:XF 3 "immediate_operand" ""))]
16114   "standard_80387_constant_p (operands[3]) == 2"
16115   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16116              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16117   "")
16119 (define_expand "tanxf2"
16120   [(parallel [(set (match_dup 2)
16121                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16122                               UNSPEC_TAN_ONE))
16123               (set (match_operand:XF 0 "register_operand" "")
16124                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16125   "TARGET_USE_FANCY_MATH_387
16126    && flag_unsafe_math_optimizations"
16128   operands[2] = gen_reg_rtx (XFmode);
16131 (define_insn "atan2df3_1"
16132   [(set (match_operand:DF 0 "register_operand" "=f")
16133         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16134                     (match_operand:DF 1 "register_operand" "u")]
16135                    UNSPEC_FPATAN))
16136    (clobber (match_scratch:DF 3 "=1"))]
16137   "TARGET_USE_FANCY_MATH_387
16138    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16139    && flag_unsafe_math_optimizations"
16140   "fpatan"
16141   [(set_attr "type" "fpspc")
16142    (set_attr "mode" "DF")])
16144 (define_expand "atan2df3"
16145   [(use (match_operand:DF 0 "register_operand" ""))
16146    (use (match_operand:DF 2 "register_operand" ""))
16147    (use (match_operand:DF 1 "register_operand" ""))]
16148   "TARGET_USE_FANCY_MATH_387
16149    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16150    && flag_unsafe_math_optimizations"
16152   rtx copy = gen_reg_rtx (DFmode);
16153   emit_move_insn (copy, operands[1]);
16154   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16155   DONE;
16158 (define_expand "atandf2"
16159   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16160                    (unspec:DF [(match_dup 2)
16161                                (match_operand:DF 1 "register_operand" "")]
16162                     UNSPEC_FPATAN))
16163               (clobber (match_scratch:DF 3 ""))])]
16164   "TARGET_USE_FANCY_MATH_387
16165    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16166    && flag_unsafe_math_optimizations"
16168   operands[2] = gen_reg_rtx (DFmode);
16169   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16172 (define_insn "atan2sf3_1"
16173   [(set (match_operand:SF 0 "register_operand" "=f")
16174         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16175                     (match_operand:SF 1 "register_operand" "u")]
16176                    UNSPEC_FPATAN))
16177    (clobber (match_scratch:SF 3 "=1"))]
16178   "TARGET_USE_FANCY_MATH_387
16179    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16180    && flag_unsafe_math_optimizations"
16181   "fpatan"
16182   [(set_attr "type" "fpspc")
16183    (set_attr "mode" "SF")])
16185 (define_expand "atan2sf3"
16186   [(use (match_operand:SF 0 "register_operand" ""))
16187    (use (match_operand:SF 2 "register_operand" ""))
16188    (use (match_operand:SF 1 "register_operand" ""))]
16189   "TARGET_USE_FANCY_MATH_387
16190    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16191    && flag_unsafe_math_optimizations"
16193   rtx copy = gen_reg_rtx (SFmode);
16194   emit_move_insn (copy, operands[1]);
16195   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16196   DONE;
16199 (define_expand "atansf2"
16200   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16201                    (unspec:SF [(match_dup 2)
16202                                (match_operand:SF 1 "register_operand" "")]
16203                     UNSPEC_FPATAN))
16204               (clobber (match_scratch:SF 3 ""))])]
16205   "TARGET_USE_FANCY_MATH_387
16206    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16207    && flag_unsafe_math_optimizations"
16209   operands[2] = gen_reg_rtx (SFmode);
16210   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16213 (define_insn "atan2xf3_1"
16214   [(set (match_operand:XF 0 "register_operand" "=f")
16215         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16216                     (match_operand:XF 1 "register_operand" "u")]
16217                    UNSPEC_FPATAN))
16218    (clobber (match_scratch:XF 3 "=1"))]
16219   "TARGET_USE_FANCY_MATH_387
16220    && flag_unsafe_math_optimizations"
16221   "fpatan"
16222   [(set_attr "type" "fpspc")
16223    (set_attr "mode" "XF")])
16225 (define_expand "atan2xf3"
16226   [(use (match_operand:XF 0 "register_operand" ""))
16227    (use (match_operand:XF 2 "register_operand" ""))
16228    (use (match_operand:XF 1 "register_operand" ""))]
16229   "TARGET_USE_FANCY_MATH_387
16230    && flag_unsafe_math_optimizations"
16232   rtx copy = gen_reg_rtx (XFmode);
16233   emit_move_insn (copy, operands[1]);
16234   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16235   DONE;
16238 (define_expand "atanxf2"
16239   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16240                    (unspec:XF [(match_dup 2)
16241                                (match_operand:XF 1 "register_operand" "")]
16242                     UNSPEC_FPATAN))
16243               (clobber (match_scratch:XF 3 ""))])]
16244   "TARGET_USE_FANCY_MATH_387
16245    && flag_unsafe_math_optimizations"
16247   operands[2] = gen_reg_rtx (XFmode);
16248   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16251 (define_expand "asindf2"
16252   [(set (match_dup 2)
16253         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16254    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16255    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16256    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16257    (parallel [(set (match_dup 7)
16258                    (unspec:XF [(match_dup 6) (match_dup 2)]
16259                               UNSPEC_FPATAN))
16260               (clobber (match_scratch:XF 8 ""))])
16261    (set (match_operand:DF 0 "register_operand" "")
16262         (float_truncate:DF (match_dup 7)))]
16263   "TARGET_USE_FANCY_MATH_387
16264    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16265    && flag_unsafe_math_optimizations"
16267   int i;
16269   for (i=2; i<8; i++)
16270     operands[i] = gen_reg_rtx (XFmode);
16272   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16275 (define_expand "asinsf2"
16276   [(set (match_dup 2)
16277         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16278    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16279    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16280    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16281    (parallel [(set (match_dup 7)
16282                    (unspec:XF [(match_dup 6) (match_dup 2)]
16283                               UNSPEC_FPATAN))
16284               (clobber (match_scratch:XF 8 ""))])
16285    (set (match_operand:SF 0 "register_operand" "")
16286         (float_truncate:SF (match_dup 7)))]
16287   "TARGET_USE_FANCY_MATH_387
16288    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16289    && flag_unsafe_math_optimizations"
16291   int i;
16293   for (i=2; i<8; i++)
16294     operands[i] = gen_reg_rtx (XFmode);
16296   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16299 (define_expand "asinxf2"
16300   [(set (match_dup 2)
16301         (mult:XF (match_operand:XF 1 "register_operand" "")
16302                  (match_dup 1)))
16303    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16304    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16305    (parallel [(set (match_operand:XF 0 "register_operand" "")
16306                    (unspec:XF [(match_dup 5) (match_dup 1)]
16307                               UNSPEC_FPATAN))
16308               (clobber (match_scratch:XF 6 ""))])]
16309   "TARGET_USE_FANCY_MATH_387
16310    && flag_unsafe_math_optimizations"
16312   int i;
16314   for (i=2; i<6; i++)
16315     operands[i] = gen_reg_rtx (XFmode);
16317   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16320 (define_expand "acosdf2"
16321   [(set (match_dup 2)
16322         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16323    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16324    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16325    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16326    (parallel [(set (match_dup 7)
16327                    (unspec:XF [(match_dup 2) (match_dup 6)]
16328                               UNSPEC_FPATAN))
16329               (clobber (match_scratch:XF 8 ""))])
16330    (set (match_operand:DF 0 "register_operand" "")
16331         (float_truncate:DF (match_dup 7)))]
16332   "TARGET_USE_FANCY_MATH_387
16333    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16334    && flag_unsafe_math_optimizations"
16336   int i;
16338   for (i=2; i<8; i++)
16339     operands[i] = gen_reg_rtx (XFmode);
16341   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16344 (define_expand "acossf2"
16345   [(set (match_dup 2)
16346         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16347    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16348    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16349    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16350    (parallel [(set (match_dup 7)
16351                    (unspec:XF [(match_dup 2) (match_dup 6)]
16352                               UNSPEC_FPATAN))
16353               (clobber (match_scratch:XF 8 ""))])
16354    (set (match_operand:SF 0 "register_operand" "")
16355         (float_truncate:SF (match_dup 7)))]
16356   "TARGET_USE_FANCY_MATH_387
16357    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16358    && flag_unsafe_math_optimizations"
16360   int i;
16362   for (i=2; i<8; i++)
16363     operands[i] = gen_reg_rtx (XFmode);
16365   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16368 (define_expand "acosxf2"
16369   [(set (match_dup 2)
16370         (mult:XF (match_operand:XF 1 "register_operand" "")
16371                  (match_dup 1)))
16372    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16373    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16374    (parallel [(set (match_operand:XF 0 "register_operand" "")
16375                    (unspec:XF [(match_dup 1) (match_dup 5)]
16376                               UNSPEC_FPATAN))
16377               (clobber (match_scratch:XF 6 ""))])]
16378   "TARGET_USE_FANCY_MATH_387
16379    && flag_unsafe_math_optimizations"
16381   int i;
16383   for (i=2; i<6; i++)
16384     operands[i] = gen_reg_rtx (XFmode);
16386   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16389 (define_insn "fyl2x_xf3"
16390   [(set (match_operand:XF 0 "register_operand" "=f")
16391         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16392                     (match_operand:XF 1 "register_operand" "u")]
16393                    UNSPEC_FYL2X))
16394    (clobber (match_scratch:XF 3 "=1"))]
16395   "TARGET_USE_FANCY_MATH_387
16396    && flag_unsafe_math_optimizations"
16397   "fyl2x"
16398   [(set_attr "type" "fpspc")
16399    (set_attr "mode" "XF")])
16401 (define_expand "logsf2"
16402   [(set (match_dup 2)
16403         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16404    (parallel [(set (match_dup 4)
16405                    (unspec:XF [(match_dup 2)
16406                                (match_dup 3)] UNSPEC_FYL2X))
16407               (clobber (match_scratch:XF 5 ""))])
16408    (set (match_operand:SF 0 "register_operand" "")
16409         (float_truncate:SF (match_dup 4)))]
16410   "TARGET_USE_FANCY_MATH_387
16411    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16412    && flag_unsafe_math_optimizations"
16414   rtx temp;
16416   operands[2] = gen_reg_rtx (XFmode);
16417   operands[3] = gen_reg_rtx (XFmode);
16418   operands[4] = gen_reg_rtx (XFmode);
16420   temp = standard_80387_constant_rtx (4); /* fldln2 */
16421   emit_move_insn (operands[3], temp);
16424 (define_expand "logdf2"
16425   [(set (match_dup 2)
16426         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16427    (parallel [(set (match_dup 4)
16428                    (unspec:XF [(match_dup 2)
16429                                (match_dup 3)] UNSPEC_FYL2X))
16430               (clobber (match_scratch:XF 5 ""))])
16431    (set (match_operand:DF 0 "register_operand" "")
16432         (float_truncate:DF (match_dup 4)))]
16433   "TARGET_USE_FANCY_MATH_387
16434    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16435    && flag_unsafe_math_optimizations"
16437   rtx temp;
16439   operands[2] = gen_reg_rtx (XFmode);
16440   operands[3] = gen_reg_rtx (XFmode);
16441   operands[4] = gen_reg_rtx (XFmode);
16443   temp = standard_80387_constant_rtx (4); /* fldln2 */
16444   emit_move_insn (operands[3], temp);
16447 (define_expand "logxf2"
16448   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16449                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16450                                (match_dup 2)] UNSPEC_FYL2X))
16451               (clobber (match_scratch:XF 3 ""))])]
16452   "TARGET_USE_FANCY_MATH_387
16453    && flag_unsafe_math_optimizations"
16455   rtx temp;
16457   operands[2] = gen_reg_rtx (XFmode);
16458   temp = standard_80387_constant_rtx (4); /* fldln2 */
16459   emit_move_insn (operands[2], temp);
16462 (define_expand "log10sf2"
16463   [(set (match_dup 2)
16464         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16465    (parallel [(set (match_dup 4)
16466                    (unspec:XF [(match_dup 2)
16467                                (match_dup 3)] UNSPEC_FYL2X))
16468               (clobber (match_scratch:XF 5 ""))])
16469    (set (match_operand:SF 0 "register_operand" "")
16470         (float_truncate:SF (match_dup 4)))]
16471   "TARGET_USE_FANCY_MATH_387
16472    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16473    && flag_unsafe_math_optimizations"
16475   rtx temp;
16477   operands[2] = gen_reg_rtx (XFmode);
16478   operands[3] = gen_reg_rtx (XFmode);
16479   operands[4] = gen_reg_rtx (XFmode);
16481   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16482   emit_move_insn (operands[3], temp);
16485 (define_expand "log10df2"
16486   [(set (match_dup 2)
16487         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16488    (parallel [(set (match_dup 4)
16489                    (unspec:XF [(match_dup 2)
16490                                (match_dup 3)] UNSPEC_FYL2X))
16491               (clobber (match_scratch:XF 5 ""))])
16492    (set (match_operand:DF 0 "register_operand" "")
16493         (float_truncate:DF (match_dup 4)))]
16494   "TARGET_USE_FANCY_MATH_387
16495    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16496    && flag_unsafe_math_optimizations"
16498   rtx temp;
16500   operands[2] = gen_reg_rtx (XFmode);
16501   operands[3] = gen_reg_rtx (XFmode);
16502   operands[4] = gen_reg_rtx (XFmode);
16504   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16505   emit_move_insn (operands[3], temp);
16508 (define_expand "log10xf2"
16509   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16510                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16511                                (match_dup 2)] UNSPEC_FYL2X))
16512               (clobber (match_scratch:XF 3 ""))])]
16513   "TARGET_USE_FANCY_MATH_387
16514    && flag_unsafe_math_optimizations"
16516   rtx temp;
16518   operands[2] = gen_reg_rtx (XFmode);
16519   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16520   emit_move_insn (operands[2], temp);
16523 (define_expand "log2sf2"
16524   [(set (match_dup 2)
16525         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16526    (parallel [(set (match_dup 4)
16527                    (unspec:XF [(match_dup 2)
16528                                (match_dup 3)] UNSPEC_FYL2X))
16529               (clobber (match_scratch:XF 5 ""))])
16530    (set (match_operand:SF 0 "register_operand" "")
16531         (float_truncate:SF (match_dup 4)))]
16532   "TARGET_USE_FANCY_MATH_387
16533    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16534    && flag_unsafe_math_optimizations"
16536   operands[2] = gen_reg_rtx (XFmode);
16537   operands[3] = gen_reg_rtx (XFmode);
16538   operands[4] = gen_reg_rtx (XFmode);
16540   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16543 (define_expand "log2df2"
16544   [(set (match_dup 2)
16545         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16546    (parallel [(set (match_dup 4)
16547                    (unspec:XF [(match_dup 2)
16548                                (match_dup 3)] UNSPEC_FYL2X))
16549               (clobber (match_scratch:XF 5 ""))])
16550    (set (match_operand:DF 0 "register_operand" "")
16551         (float_truncate:DF (match_dup 4)))]
16552   "TARGET_USE_FANCY_MATH_387
16553    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16554    && flag_unsafe_math_optimizations"
16556   operands[2] = gen_reg_rtx (XFmode);
16557   operands[3] = gen_reg_rtx (XFmode);
16558   operands[4] = gen_reg_rtx (XFmode);
16560   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16563 (define_expand "log2xf2"
16564   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16565                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16566                                (match_dup 2)] UNSPEC_FYL2X))
16567               (clobber (match_scratch:XF 3 ""))])]
16568   "TARGET_USE_FANCY_MATH_387
16569    && flag_unsafe_math_optimizations"
16571   operands[2] = gen_reg_rtx (XFmode);
16572   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16575 (define_insn "fyl2xp1_xf3"
16576   [(set (match_operand:XF 0 "register_operand" "=f")
16577         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16578                     (match_operand:XF 1 "register_operand" "u")]
16579                    UNSPEC_FYL2XP1))
16580    (clobber (match_scratch:XF 3 "=1"))]
16581   "TARGET_USE_FANCY_MATH_387
16582    && flag_unsafe_math_optimizations"
16583   "fyl2xp1"
16584   [(set_attr "type" "fpspc")
16585    (set_attr "mode" "XF")])
16587 (define_expand "log1psf2"
16588   [(use (match_operand:SF 0 "register_operand" ""))
16589    (use (match_operand:SF 1 "register_operand" ""))]
16590   "TARGET_USE_FANCY_MATH_387
16591    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16592    && flag_unsafe_math_optimizations"
16594   rtx op0 = gen_reg_rtx (XFmode);
16595   rtx op1 = gen_reg_rtx (XFmode);
16597   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16598   ix86_emit_i387_log1p (op0, op1);
16599   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16600   DONE;
16603 (define_expand "log1pdf2"
16604   [(use (match_operand:DF 0 "register_operand" ""))
16605    (use (match_operand:DF 1 "register_operand" ""))]
16606   "TARGET_USE_FANCY_MATH_387
16607    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16608    && flag_unsafe_math_optimizations"
16610   rtx op0 = gen_reg_rtx (XFmode);
16611   rtx op1 = gen_reg_rtx (XFmode);
16613   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16614   ix86_emit_i387_log1p (op0, op1);
16615   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16616   DONE;
16619 (define_expand "log1pxf2"
16620   [(use (match_operand:XF 0 "register_operand" ""))
16621    (use (match_operand:XF 1 "register_operand" ""))]
16622   "TARGET_USE_FANCY_MATH_387
16623    && flag_unsafe_math_optimizations"
16625   ix86_emit_i387_log1p (operands[0], operands[1]);
16626   DONE;
16629 (define_insn "*fxtractxf3"
16630   [(set (match_operand:XF 0 "register_operand" "=f")
16631         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16632                    UNSPEC_XTRACT_FRACT))
16633    (set (match_operand:XF 1 "register_operand" "=u")
16634         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16635   "TARGET_USE_FANCY_MATH_387
16636    && flag_unsafe_math_optimizations"
16637   "fxtract"
16638   [(set_attr "type" "fpspc")
16639    (set_attr "mode" "XF")])
16641 (define_expand "logbsf2"
16642   [(set (match_dup 2)
16643         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16644    (parallel [(set (match_dup 3)
16645                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16646               (set (match_dup 4)
16647                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16648    (set (match_operand:SF 0 "register_operand" "")
16649         (float_truncate:SF (match_dup 4)))]
16650   "TARGET_USE_FANCY_MATH_387
16651    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16652    && flag_unsafe_math_optimizations"
16654   operands[2] = gen_reg_rtx (XFmode);
16655   operands[3] = gen_reg_rtx (XFmode);
16656   operands[4] = gen_reg_rtx (XFmode);
16659 (define_expand "logbdf2"
16660   [(set (match_dup 2)
16661         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16662    (parallel [(set (match_dup 3)
16663                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16664               (set (match_dup 4)
16665                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16666    (set (match_operand:DF 0 "register_operand" "")
16667         (float_truncate:DF (match_dup 4)))]
16668   "TARGET_USE_FANCY_MATH_387
16669    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16670    && flag_unsafe_math_optimizations"
16672   operands[2] = gen_reg_rtx (XFmode);
16673   operands[3] = gen_reg_rtx (XFmode);
16674   operands[4] = gen_reg_rtx (XFmode);
16677 (define_expand "logbxf2"
16678   [(parallel [(set (match_dup 2)
16679                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16680                               UNSPEC_XTRACT_FRACT))
16681               (set (match_operand:XF 0 "register_operand" "")
16682                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16683   "TARGET_USE_FANCY_MATH_387
16684    && flag_unsafe_math_optimizations"
16686   operands[2] = gen_reg_rtx (XFmode);
16689 (define_expand "ilogbsi2"
16690   [(parallel [(set (match_dup 2)
16691                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16692                               UNSPEC_XTRACT_FRACT))
16693               (set (match_operand:XF 3 "register_operand" "")
16694                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16695    (parallel [(set (match_operand:SI 0 "register_operand" "")
16696                    (fix:SI (match_dup 3)))
16697               (clobber (reg:CC FLAGS_REG))])]
16698   "TARGET_USE_FANCY_MATH_387
16699    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16700    && flag_unsafe_math_optimizations"
16702   operands[2] = gen_reg_rtx (XFmode);
16703   operands[3] = gen_reg_rtx (XFmode);
16706 (define_insn "*f2xm1xf2"
16707   [(set (match_operand:XF 0 "register_operand" "=f")
16708         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16709          UNSPEC_F2XM1))]
16710   "TARGET_USE_FANCY_MATH_387
16711    && flag_unsafe_math_optimizations"
16712   "f2xm1"
16713   [(set_attr "type" "fpspc")
16714    (set_attr "mode" "XF")])
16716 (define_insn "*fscalexf4"
16717   [(set (match_operand:XF 0 "register_operand" "=f")
16718         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16719                     (match_operand:XF 3 "register_operand" "1")]
16720                    UNSPEC_FSCALE_FRACT))
16721    (set (match_operand:XF 1 "register_operand" "=u")
16722         (unspec:XF [(match_dup 2) (match_dup 3)]
16723                    UNSPEC_FSCALE_EXP))]
16724   "TARGET_USE_FANCY_MATH_387
16725    && flag_unsafe_math_optimizations"
16726   "fscale"
16727   [(set_attr "type" "fpspc")
16728    (set_attr "mode" "XF")])
16730 (define_expand "expsf2"
16731   [(set (match_dup 2)
16732         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16733    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16734    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16735    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16736    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16737    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16738    (parallel [(set (match_dup 10)
16739                    (unspec:XF [(match_dup 9) (match_dup 5)]
16740                               UNSPEC_FSCALE_FRACT))
16741               (set (match_dup 11)
16742                    (unspec:XF [(match_dup 9) (match_dup 5)]
16743                               UNSPEC_FSCALE_EXP))])
16744    (set (match_operand:SF 0 "register_operand" "")
16745         (float_truncate:SF (match_dup 10)))]
16746   "TARGET_USE_FANCY_MATH_387
16747    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16748    && flag_unsafe_math_optimizations"
16750   rtx temp;
16751   int i;
16753   for (i=2; i<12; i++)
16754     operands[i] = gen_reg_rtx (XFmode);
16755   temp = standard_80387_constant_rtx (5); /* fldl2e */
16756   emit_move_insn (operands[3], temp);
16757   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16760 (define_expand "expdf2"
16761   [(set (match_dup 2)
16762         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16763    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16764    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16765    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16766    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16767    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16768    (parallel [(set (match_dup 10)
16769                    (unspec:XF [(match_dup 9) (match_dup 5)]
16770                               UNSPEC_FSCALE_FRACT))
16771               (set (match_dup 11)
16772                    (unspec:XF [(match_dup 9) (match_dup 5)]
16773                               UNSPEC_FSCALE_EXP))])
16774    (set (match_operand:DF 0 "register_operand" "")
16775         (float_truncate:DF (match_dup 10)))]
16776   "TARGET_USE_FANCY_MATH_387
16777    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16778    && flag_unsafe_math_optimizations"
16780   rtx temp;
16781   int i;
16783   for (i=2; i<12; i++)
16784     operands[i] = gen_reg_rtx (XFmode);
16785   temp = standard_80387_constant_rtx (5); /* fldl2e */
16786   emit_move_insn (operands[3], temp);
16787   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16790 (define_expand "expxf2"
16791   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16792                                (match_dup 2)))
16793    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16794    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16795    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16796    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16797    (parallel [(set (match_operand:XF 0 "register_operand" "")
16798                    (unspec:XF [(match_dup 8) (match_dup 4)]
16799                               UNSPEC_FSCALE_FRACT))
16800               (set (match_dup 9)
16801                    (unspec:XF [(match_dup 8) (match_dup 4)]
16802                               UNSPEC_FSCALE_EXP))])]
16803   "TARGET_USE_FANCY_MATH_387
16804    && flag_unsafe_math_optimizations"
16806   rtx temp;
16807   int i;
16809   for (i=2; i<10; i++)
16810     operands[i] = gen_reg_rtx (XFmode);
16811   temp = standard_80387_constant_rtx (5); /* fldl2e */
16812   emit_move_insn (operands[2], temp);
16813   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16816 (define_expand "exp10sf2"
16817   [(set (match_dup 2)
16818         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16819    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16820    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16821    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16822    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16823    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16824    (parallel [(set (match_dup 10)
16825                    (unspec:XF [(match_dup 9) (match_dup 5)]
16826                               UNSPEC_FSCALE_FRACT))
16827               (set (match_dup 11)
16828                    (unspec:XF [(match_dup 9) (match_dup 5)]
16829                               UNSPEC_FSCALE_EXP))])
16830    (set (match_operand:SF 0 "register_operand" "")
16831         (float_truncate:SF (match_dup 10)))]
16832   "TARGET_USE_FANCY_MATH_387
16833    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16834    && flag_unsafe_math_optimizations"
16836   rtx temp;
16837   int i;
16839   for (i=2; i<12; i++)
16840     operands[i] = gen_reg_rtx (XFmode);
16841   temp = standard_80387_constant_rtx (6); /* fldl2t */
16842   emit_move_insn (operands[3], temp);
16843   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16846 (define_expand "exp10df2"
16847   [(set (match_dup 2)
16848         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16849    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16850    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16851    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16852    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16853    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16854    (parallel [(set (match_dup 10)
16855                    (unspec:XF [(match_dup 9) (match_dup 5)]
16856                               UNSPEC_FSCALE_FRACT))
16857               (set (match_dup 11)
16858                    (unspec:XF [(match_dup 9) (match_dup 5)]
16859                               UNSPEC_FSCALE_EXP))])
16860    (set (match_operand:DF 0 "register_operand" "")
16861         (float_truncate:DF (match_dup 10)))]
16862   "TARGET_USE_FANCY_MATH_387
16863    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16864    && flag_unsafe_math_optimizations"
16866   rtx temp;
16867   int i;
16869   for (i=2; i<12; i++)
16870     operands[i] = gen_reg_rtx (XFmode);
16871   temp = standard_80387_constant_rtx (6); /* fldl2t */
16872   emit_move_insn (operands[3], temp);
16873   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16876 (define_expand "exp10xf2"
16877   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16878                                (match_dup 2)))
16879    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16880    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16881    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16882    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16883    (parallel [(set (match_operand:XF 0 "register_operand" "")
16884                    (unspec:XF [(match_dup 8) (match_dup 4)]
16885                               UNSPEC_FSCALE_FRACT))
16886               (set (match_dup 9)
16887                    (unspec:XF [(match_dup 8) (match_dup 4)]
16888                               UNSPEC_FSCALE_EXP))])]
16889   "TARGET_USE_FANCY_MATH_387
16890    && flag_unsafe_math_optimizations"
16892   rtx temp;
16893   int i;
16895   for (i=2; i<10; i++)
16896     operands[i] = gen_reg_rtx (XFmode);
16897   temp = standard_80387_constant_rtx (6); /* fldl2t */
16898   emit_move_insn (operands[2], temp);
16899   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16902 (define_expand "exp2sf2"
16903   [(set (match_dup 2)
16904         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16905    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16906    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16907    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16908    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16909    (parallel [(set (match_dup 8)
16910                    (unspec:XF [(match_dup 7) (match_dup 3)]
16911                               UNSPEC_FSCALE_FRACT))
16912               (set (match_dup 9)
16913                    (unspec:XF [(match_dup 7) (match_dup 3)]
16914                               UNSPEC_FSCALE_EXP))])
16915    (set (match_operand:SF 0 "register_operand" "")
16916         (float_truncate:SF (match_dup 8)))]
16917   "TARGET_USE_FANCY_MATH_387
16918    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16919    && flag_unsafe_math_optimizations"
16921   int i;
16923   for (i=2; i<10; i++)
16924     operands[i] = gen_reg_rtx (XFmode);
16925   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16928 (define_expand "exp2df2"
16929   [(set (match_dup 2)
16930         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16931    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16932    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16933    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16934    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16935    (parallel [(set (match_dup 8)
16936                    (unspec:XF [(match_dup 7) (match_dup 3)]
16937                               UNSPEC_FSCALE_FRACT))
16938               (set (match_dup 9)
16939                    (unspec:XF [(match_dup 7) (match_dup 3)]
16940                               UNSPEC_FSCALE_EXP))])
16941    (set (match_operand:DF 0 "register_operand" "")
16942         (float_truncate:DF (match_dup 8)))]
16943   "TARGET_USE_FANCY_MATH_387
16944    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16945    && flag_unsafe_math_optimizations"
16947   int i;
16949   for (i=2; i<10; i++)
16950     operands[i] = gen_reg_rtx (XFmode);
16951   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16954 (define_expand "exp2xf2"
16955   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16956    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16957    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16958    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16959    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16960    (parallel [(set (match_operand:XF 0 "register_operand" "")
16961                    (unspec:XF [(match_dup 7) (match_dup 3)]
16962                               UNSPEC_FSCALE_FRACT))
16963               (set (match_dup 8)
16964                    (unspec:XF [(match_dup 7) (match_dup 3)]
16965                               UNSPEC_FSCALE_EXP))])]
16966   "TARGET_USE_FANCY_MATH_387
16967    && flag_unsafe_math_optimizations"
16969   int i;
16971   for (i=2; i<9; i++)
16972     operands[i] = gen_reg_rtx (XFmode);
16973   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16976 (define_expand "expm1df2"
16977   [(set (match_dup 2)
16978         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16979    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16980    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16981    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16982    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16983    (parallel [(set (match_dup 8)
16984                    (unspec:XF [(match_dup 7) (match_dup 5)]
16985                               UNSPEC_FSCALE_FRACT))
16986                    (set (match_dup 9)
16987                    (unspec:XF [(match_dup 7) (match_dup 5)]
16988                               UNSPEC_FSCALE_EXP))])
16989    (parallel [(set (match_dup 11)
16990                    (unspec:XF [(match_dup 10) (match_dup 9)]
16991                               UNSPEC_FSCALE_FRACT))
16992               (set (match_dup 12)
16993                    (unspec:XF [(match_dup 10) (match_dup 9)]
16994                               UNSPEC_FSCALE_EXP))])
16995    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16996    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16997    (set (match_operand:DF 0 "register_operand" "")
16998         (float_truncate:DF (match_dup 14)))]
16999   "TARGET_USE_FANCY_MATH_387
17000    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17001    && flag_unsafe_math_optimizations"
17003   rtx temp;
17004   int i;
17006   for (i=2; i<15; i++)
17007     operands[i] = gen_reg_rtx (XFmode);
17008   temp = standard_80387_constant_rtx (5); /* fldl2e */
17009   emit_move_insn (operands[3], temp);
17010   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17013 (define_expand "expm1sf2"
17014   [(set (match_dup 2)
17015         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17016    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17017    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17018    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17019    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17020    (parallel [(set (match_dup 8)
17021                    (unspec:XF [(match_dup 7) (match_dup 5)]
17022                               UNSPEC_FSCALE_FRACT))
17023                    (set (match_dup 9)
17024                    (unspec:XF [(match_dup 7) (match_dup 5)]
17025                               UNSPEC_FSCALE_EXP))])
17026    (parallel [(set (match_dup 11)
17027                    (unspec:XF [(match_dup 10) (match_dup 9)]
17028                               UNSPEC_FSCALE_FRACT))
17029               (set (match_dup 12)
17030                    (unspec:XF [(match_dup 10) (match_dup 9)]
17031                               UNSPEC_FSCALE_EXP))])
17032    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17033    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17034    (set (match_operand:SF 0 "register_operand" "")
17035         (float_truncate:SF (match_dup 14)))]
17036   "TARGET_USE_FANCY_MATH_387
17037    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17038    && flag_unsafe_math_optimizations"
17040   rtx temp;
17041   int i;
17043   for (i=2; i<15; i++)
17044     operands[i] = gen_reg_rtx (XFmode);
17045   temp = standard_80387_constant_rtx (5); /* fldl2e */
17046   emit_move_insn (operands[3], temp);
17047   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17050 (define_expand "expm1xf2"
17051   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17052                                (match_dup 2)))
17053    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17054    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17055    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17056    (parallel [(set (match_dup 7)
17057                    (unspec:XF [(match_dup 6) (match_dup 4)]
17058                               UNSPEC_FSCALE_FRACT))
17059                    (set (match_dup 8)
17060                    (unspec:XF [(match_dup 6) (match_dup 4)]
17061                               UNSPEC_FSCALE_EXP))])
17062    (parallel [(set (match_dup 10)
17063                    (unspec:XF [(match_dup 9) (match_dup 8)]
17064                               UNSPEC_FSCALE_FRACT))
17065               (set (match_dup 11)
17066                    (unspec:XF [(match_dup 9) (match_dup 8)]
17067                               UNSPEC_FSCALE_EXP))])
17068    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17069    (set (match_operand:XF 0 "register_operand" "")
17070         (plus:XF (match_dup 12) (match_dup 7)))]
17071   "TARGET_USE_FANCY_MATH_387
17072    && flag_unsafe_math_optimizations"
17074   rtx temp;
17075   int i;
17077   for (i=2; i<13; i++)
17078     operands[i] = gen_reg_rtx (XFmode);
17079   temp = standard_80387_constant_rtx (5); /* fldl2e */
17080   emit_move_insn (operands[2], temp);
17081   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17084 (define_expand "ldexpdf3"
17085   [(set (match_dup 3)
17086         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17087    (set (match_dup 4)
17088         (float:XF (match_operand:SI 2 "register_operand" "")))
17089    (parallel [(set (match_dup 5)
17090                    (unspec:XF [(match_dup 3) (match_dup 4)]
17091                               UNSPEC_FSCALE_FRACT))
17092               (set (match_dup 6)
17093                    (unspec:XF [(match_dup 3) (match_dup 4)]
17094                               UNSPEC_FSCALE_EXP))])
17095    (set (match_operand:DF 0 "register_operand" "")
17096         (float_truncate:DF (match_dup 5)))]
17097   "TARGET_USE_FANCY_MATH_387
17098    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17099    && flag_unsafe_math_optimizations"
17101   int i;
17103   for (i=3; i<7; i++)
17104     operands[i] = gen_reg_rtx (XFmode);
17107 (define_expand "ldexpsf3"
17108   [(set (match_dup 3)
17109         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17110    (set (match_dup 4)
17111         (float:XF (match_operand:SI 2 "register_operand" "")))
17112    (parallel [(set (match_dup 5)
17113                    (unspec:XF [(match_dup 3) (match_dup 4)]
17114                               UNSPEC_FSCALE_FRACT))
17115               (set (match_dup 6)
17116                    (unspec:XF [(match_dup 3) (match_dup 4)]
17117                               UNSPEC_FSCALE_EXP))])
17118    (set (match_operand:SF 0 "register_operand" "")
17119         (float_truncate:SF (match_dup 5)))]
17120   "TARGET_USE_FANCY_MATH_387
17121    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17122    && flag_unsafe_math_optimizations"
17124   int i;
17126   for (i=3; i<7; i++)
17127     operands[i] = gen_reg_rtx (XFmode);
17130 (define_expand "ldexpxf3"
17131   [(set (match_dup 3)
17132         (float:XF (match_operand:SI 2 "register_operand" "")))
17133    (parallel [(set (match_operand:XF 0 " register_operand" "")
17134                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17135                                (match_dup 3)]
17136                               UNSPEC_FSCALE_FRACT))
17137               (set (match_dup 4)
17138                    (unspec:XF [(match_dup 1) (match_dup 3)]
17139                               UNSPEC_FSCALE_EXP))])]
17140   "TARGET_USE_FANCY_MATH_387
17141    && flag_unsafe_math_optimizations"
17143   int i;
17145   for (i=3; i<5; i++)
17146     operands[i] = gen_reg_rtx (XFmode);
17150 (define_insn "frndintxf2"
17151   [(set (match_operand:XF 0 "register_operand" "=f")
17152         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17153          UNSPEC_FRNDINT))]
17154   "TARGET_USE_FANCY_MATH_387
17155    && flag_unsafe_math_optimizations"
17156   "frndint"
17157   [(set_attr "type" "fpspc")
17158    (set_attr "mode" "XF")])
17160 (define_expand "rintdf2"
17161   [(use (match_operand:DF 0 "register_operand" ""))
17162    (use (match_operand:DF 1 "register_operand" ""))]
17163   "TARGET_USE_FANCY_MATH_387
17164    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17165    && flag_unsafe_math_optimizations"
17167   rtx op0 = gen_reg_rtx (XFmode);
17168   rtx op1 = gen_reg_rtx (XFmode);
17170   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17171   emit_insn (gen_frndintxf2 (op0, op1));
17173   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17174   DONE;
17177 (define_expand "rintsf2"
17178   [(use (match_operand:SF 0 "register_operand" ""))
17179    (use (match_operand:SF 1 "register_operand" ""))]
17180   "TARGET_USE_FANCY_MATH_387
17181    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17182    && flag_unsafe_math_optimizations"
17184   rtx op0 = gen_reg_rtx (XFmode);
17185   rtx op1 = gen_reg_rtx (XFmode);
17187   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17188   emit_insn (gen_frndintxf2 (op0, op1));
17190   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17191   DONE;
17194 (define_expand "rintxf2"
17195   [(use (match_operand:XF 0 "register_operand" ""))
17196    (use (match_operand:XF 1 "register_operand" ""))]
17197   "TARGET_USE_FANCY_MATH_387
17198    && flag_unsafe_math_optimizations"
17200   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17201   DONE;
17204 (define_insn_and_split "*fistdi2_1"
17205   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17206         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17207          UNSPEC_FIST))]
17208   "TARGET_USE_FANCY_MATH_387
17209    && !(reload_completed || reload_in_progress)"
17210   "#"
17211   "&& 1"
17212   [(const_int 0)]
17214   if (memory_operand (operands[0], VOIDmode))
17215     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17216   else
17217     {
17218       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17219       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17220                                          operands[2]));
17221     }
17222   DONE;
17224   [(set_attr "type" "fpspc")
17225    (set_attr "mode" "DI")])
17227 (define_insn "fistdi2"
17228   [(set (match_operand:DI 0 "memory_operand" "=m")
17229         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17230          UNSPEC_FIST))
17231    (clobber (match_scratch:XF 2 "=&1f"))]
17232   "TARGET_USE_FANCY_MATH_387"
17233   "* return output_fix_trunc (insn, operands, 0);"
17234   [(set_attr "type" "fpspc")
17235    (set_attr "mode" "DI")])
17237 (define_insn "fistdi2_with_temp"
17238   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17239         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17240          UNSPEC_FIST))
17241    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17242    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17243   "TARGET_USE_FANCY_MATH_387"
17244   "#"
17245   [(set_attr "type" "fpspc")
17246    (set_attr "mode" "DI")])
17248 (define_split 
17249   [(set (match_operand:DI 0 "register_operand" "")
17250         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17251          UNSPEC_FIST))
17252    (clobber (match_operand:DI 2 "memory_operand" ""))
17253    (clobber (match_scratch 3 ""))]
17254   "reload_completed"
17255   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17256               (clobber (match_dup 3))])
17257    (set (match_dup 0) (match_dup 2))]
17258   "")
17260 (define_split 
17261   [(set (match_operand:DI 0 "memory_operand" "")
17262         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17263          UNSPEC_FIST))
17264    (clobber (match_operand:DI 2 "memory_operand" ""))
17265    (clobber (match_scratch 3 ""))]
17266   "reload_completed"
17267   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17268               (clobber (match_dup 3))])]
17269   "")
17271 (define_insn_and_split "*fist<mode>2_1"
17272   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17273         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17274          UNSPEC_FIST))]
17275   "TARGET_USE_FANCY_MATH_387
17276    && !(reload_completed || reload_in_progress)"
17277   "#"
17278   "&& 1"
17279   [(const_int 0)]
17281   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17282   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17283                                         operands[2]));
17284   DONE;
17286   [(set_attr "type" "fpspc")
17287    (set_attr "mode" "<MODE>")])
17289 (define_insn "fist<mode>2"
17290   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17291         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17292          UNSPEC_FIST))]
17293   "TARGET_USE_FANCY_MATH_387"
17294   "* return output_fix_trunc (insn, operands, 0);"
17295   [(set_attr "type" "fpspc")
17296    (set_attr "mode" "<MODE>")])
17298 (define_insn "fist<mode>2_with_temp"
17299   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17300         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17301          UNSPEC_FIST))
17302    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17303   "TARGET_USE_FANCY_MATH_387"
17304   "#"
17305   [(set_attr "type" "fpspc")
17306    (set_attr "mode" "<MODE>")])
17308 (define_split 
17309   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17310         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17311          UNSPEC_FIST))
17312    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17313   "reload_completed"
17314   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17315                        UNSPEC_FIST))
17316    (set (match_dup 0) (match_dup 2))]
17317   "")
17319 (define_split 
17320   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17321         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17322          UNSPEC_FIST))
17323    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17324   "reload_completed"
17325   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17326                        UNSPEC_FIST))]
17327   "")
17329 (define_expand "lrintxf<mode>2"
17330   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17331      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17332       UNSPEC_FIST))]
17333   "TARGET_USE_FANCY_MATH_387"
17334   "")
17336 (define_expand "lrint<mode>di2"
17337   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17338      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17339       UNSPEC_FIX_NOTRUNC))]
17340   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17341   "")
17343 (define_expand "lrint<mode>si2"
17344   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17345      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17346       UNSPEC_FIX_NOTRUNC))]
17347   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17348   "")
17350 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17351 (define_insn_and_split "frndintxf2_floor"
17352   [(set (match_operand:XF 0 "register_operand" "=f")
17353         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17354          UNSPEC_FRNDINT_FLOOR))
17355    (clobber (reg:CC FLAGS_REG))]
17356   "TARGET_USE_FANCY_MATH_387
17357    && flag_unsafe_math_optimizations
17358    && !(reload_completed || reload_in_progress)"
17359   "#"
17360   "&& 1"
17361   [(const_int 0)]
17363   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17365   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17366   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17368   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17369                                         operands[2], operands[3]));
17370   DONE;
17372   [(set_attr "type" "frndint")
17373    (set_attr "i387_cw" "floor")
17374    (set_attr "mode" "XF")])
17376 (define_insn "frndintxf2_floor_i387"
17377   [(set (match_operand:XF 0 "register_operand" "=f")
17378         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17379          UNSPEC_FRNDINT_FLOOR))
17380    (use (match_operand:HI 2 "memory_operand" "m"))
17381    (use (match_operand:HI 3 "memory_operand" "m"))]
17382   "TARGET_USE_FANCY_MATH_387
17383    && flag_unsafe_math_optimizations"
17384   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17385   [(set_attr "type" "frndint")
17386    (set_attr "i387_cw" "floor")
17387    (set_attr "mode" "XF")])
17389 (define_expand "floorxf2"
17390   [(use (match_operand:XF 0 "register_operand" ""))
17391    (use (match_operand:XF 1 "register_operand" ""))]
17392   "TARGET_USE_FANCY_MATH_387
17393    && flag_unsafe_math_optimizations"
17395   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17396   DONE;
17399 (define_expand "floordf2"
17400   [(use (match_operand:DF 0 "register_operand" ""))
17401    (use (match_operand:DF 1 "register_operand" ""))]
17402   "TARGET_USE_FANCY_MATH_387
17403    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17404    && flag_unsafe_math_optimizations"
17406   rtx op0 = gen_reg_rtx (XFmode);
17407   rtx op1 = gen_reg_rtx (XFmode);
17409   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17410   emit_insn (gen_frndintxf2_floor (op0, op1));
17412   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17413   DONE;
17416 (define_expand "floorsf2"
17417   [(use (match_operand:SF 0 "register_operand" ""))
17418    (use (match_operand:SF 1 "register_operand" ""))]
17419   "TARGET_USE_FANCY_MATH_387
17420    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17421    && flag_unsafe_math_optimizations"
17423   rtx op0 = gen_reg_rtx (XFmode);
17424   rtx op1 = gen_reg_rtx (XFmode);
17426   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17427   emit_insn (gen_frndintxf2_floor (op0, op1));
17429   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17430   DONE;
17433 (define_insn_and_split "*fist<mode>2_floor_1"
17434   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17435         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17436          UNSPEC_FIST_FLOOR))
17437    (clobber (reg:CC FLAGS_REG))]
17438   "TARGET_USE_FANCY_MATH_387
17439    && flag_unsafe_math_optimizations
17440    && !(reload_completed || reload_in_progress)"
17441   "#"
17442   "&& 1"
17443   [(const_int 0)]
17445   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17447   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17448   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17449   if (memory_operand (operands[0], VOIDmode))
17450     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17451                                       operands[2], operands[3]));
17452   else
17453     {
17454       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17455       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17456                                                   operands[2], operands[3],
17457                                                   operands[4]));
17458     }
17459   DONE;
17461   [(set_attr "type" "fistp")
17462    (set_attr "i387_cw" "floor")
17463    (set_attr "mode" "<MODE>")])
17465 (define_insn "fistdi2_floor"
17466   [(set (match_operand:DI 0 "memory_operand" "=m")
17467         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17468          UNSPEC_FIST_FLOOR))
17469    (use (match_operand:HI 2 "memory_operand" "m"))
17470    (use (match_operand:HI 3 "memory_operand" "m"))
17471    (clobber (match_scratch:XF 4 "=&1f"))]
17472   "TARGET_USE_FANCY_MATH_387
17473    && flag_unsafe_math_optimizations"
17474   "* return output_fix_trunc (insn, operands, 0);"
17475   [(set_attr "type" "fistp")
17476    (set_attr "i387_cw" "floor")
17477    (set_attr "mode" "DI")])
17479 (define_insn "fistdi2_floor_with_temp"
17480   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17481         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17482          UNSPEC_FIST_FLOOR))
17483    (use (match_operand:HI 2 "memory_operand" "m,m"))
17484    (use (match_operand:HI 3 "memory_operand" "m,m"))
17485    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17486    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17487   "TARGET_USE_FANCY_MATH_387
17488    && flag_unsafe_math_optimizations"
17489   "#"
17490   [(set_attr "type" "fistp")
17491    (set_attr "i387_cw" "floor")
17492    (set_attr "mode" "DI")])
17494 (define_split 
17495   [(set (match_operand:DI 0 "register_operand" "")
17496         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17497          UNSPEC_FIST_FLOOR))
17498    (use (match_operand:HI 2 "memory_operand" ""))
17499    (use (match_operand:HI 3 "memory_operand" ""))
17500    (clobber (match_operand:DI 4 "memory_operand" ""))
17501    (clobber (match_scratch 5 ""))]
17502   "reload_completed"
17503   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17504               (use (match_dup 2))
17505               (use (match_dup 3))
17506               (clobber (match_dup 5))])
17507    (set (match_dup 0) (match_dup 4))]
17508   "")
17510 (define_split 
17511   [(set (match_operand:DI 0 "memory_operand" "")
17512         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17513          UNSPEC_FIST_FLOOR))
17514    (use (match_operand:HI 2 "memory_operand" ""))
17515    (use (match_operand:HI 3 "memory_operand" ""))
17516    (clobber (match_operand:DI 4 "memory_operand" ""))
17517    (clobber (match_scratch 5 ""))]
17518   "reload_completed"
17519   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17520               (use (match_dup 2))
17521               (use (match_dup 3))
17522               (clobber (match_dup 5))])]
17523   "")
17525 (define_insn "fist<mode>2_floor"
17526   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17527         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17528          UNSPEC_FIST_FLOOR))
17529    (use (match_operand:HI 2 "memory_operand" "m"))
17530    (use (match_operand:HI 3 "memory_operand" "m"))]
17531   "TARGET_USE_FANCY_MATH_387
17532    && flag_unsafe_math_optimizations"
17533   "* return output_fix_trunc (insn, operands, 0);"
17534   [(set_attr "type" "fistp")
17535    (set_attr "i387_cw" "floor")
17536    (set_attr "mode" "<MODE>")])
17538 (define_insn "fist<mode>2_floor_with_temp"
17539   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17540         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17541          UNSPEC_FIST_FLOOR))
17542    (use (match_operand:HI 2 "memory_operand" "m,m"))
17543    (use (match_operand:HI 3 "memory_operand" "m,m"))
17544    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17545   "TARGET_USE_FANCY_MATH_387
17546    && flag_unsafe_math_optimizations"
17547   "#"
17548   [(set_attr "type" "fistp")
17549    (set_attr "i387_cw" "floor")
17550    (set_attr "mode" "<MODE>")])
17552 (define_split 
17553   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17554         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17555          UNSPEC_FIST_FLOOR))
17556    (use (match_operand:HI 2 "memory_operand" ""))
17557    (use (match_operand:HI 3 "memory_operand" ""))
17558    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17559   "reload_completed"
17560   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17561                                   UNSPEC_FIST_FLOOR))
17562               (use (match_dup 2))
17563               (use (match_dup 3))])
17564    (set (match_dup 0) (match_dup 4))]
17565   "")
17567 (define_split 
17568   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17569         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17570          UNSPEC_FIST_FLOOR))
17571    (use (match_operand:HI 2 "memory_operand" ""))
17572    (use (match_operand:HI 3 "memory_operand" ""))
17573    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17574   "reload_completed"
17575   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17576                                   UNSPEC_FIST_FLOOR))
17577               (use (match_dup 2))
17578               (use (match_dup 3))])]
17579   "")
17581 (define_expand "lfloor<mode>2"
17582   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17583                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17584                     UNSPEC_FIST_FLOOR))
17585               (clobber (reg:CC FLAGS_REG))])]
17586   "TARGET_USE_FANCY_MATH_387
17587    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17588    && flag_unsafe_math_optimizations"
17589   "")
17591 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17592 (define_insn_and_split "frndintxf2_ceil"
17593   [(set (match_operand:XF 0 "register_operand" "=f")
17594         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17595          UNSPEC_FRNDINT_CEIL))
17596    (clobber (reg:CC FLAGS_REG))]
17597   "TARGET_USE_FANCY_MATH_387
17598    && flag_unsafe_math_optimizations
17599    && !(reload_completed || reload_in_progress)"
17600   "#"
17601   "&& 1"
17602   [(const_int 0)]
17604   ix86_optimize_mode_switching[I387_CEIL] = 1;
17606   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17607   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17609   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17610                                        operands[2], operands[3]));
17611   DONE;
17613   [(set_attr "type" "frndint")
17614    (set_attr "i387_cw" "ceil")
17615    (set_attr "mode" "XF")])
17617 (define_insn "frndintxf2_ceil_i387"
17618   [(set (match_operand:XF 0 "register_operand" "=f")
17619         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17620          UNSPEC_FRNDINT_CEIL))
17621    (use (match_operand:HI 2 "memory_operand" "m"))
17622    (use (match_operand:HI 3 "memory_operand" "m"))]
17623   "TARGET_USE_FANCY_MATH_387
17624    && flag_unsafe_math_optimizations"
17625   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17626   [(set_attr "type" "frndint")
17627    (set_attr "i387_cw" "ceil")
17628    (set_attr "mode" "XF")])
17630 (define_expand "ceilxf2"
17631   [(use (match_operand:XF 0 "register_operand" ""))
17632    (use (match_operand:XF 1 "register_operand" ""))]
17633   "TARGET_USE_FANCY_MATH_387
17634    && flag_unsafe_math_optimizations"
17636   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17637   DONE;
17640 (define_expand "ceildf2"
17641   [(use (match_operand:DF 0 "register_operand" ""))
17642    (use (match_operand:DF 1 "register_operand" ""))]
17643   "TARGET_USE_FANCY_MATH_387
17644    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17645    && flag_unsafe_math_optimizations"
17647   rtx op0 = gen_reg_rtx (XFmode);
17648   rtx op1 = gen_reg_rtx (XFmode);
17650   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17651   emit_insn (gen_frndintxf2_ceil (op0, op1));
17653   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17654   DONE;
17657 (define_expand "ceilsf2"
17658   [(use (match_operand:SF 0 "register_operand" ""))
17659    (use (match_operand:SF 1 "register_operand" ""))]
17660   "TARGET_USE_FANCY_MATH_387
17661    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17662    && flag_unsafe_math_optimizations"
17664   rtx op0 = gen_reg_rtx (XFmode);
17665   rtx op1 = gen_reg_rtx (XFmode);
17667   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17668   emit_insn (gen_frndintxf2_ceil (op0, op1));
17670   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17671   DONE;
17674 (define_insn_and_split "*fist<mode>2_ceil_1"
17675   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17676         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17677          UNSPEC_FIST_CEIL))
17678    (clobber (reg:CC FLAGS_REG))]
17679   "TARGET_USE_FANCY_MATH_387
17680    && flag_unsafe_math_optimizations
17681    && !(reload_completed || reload_in_progress)"
17682   "#"
17683   "&& 1"
17684   [(const_int 0)]
17686   ix86_optimize_mode_switching[I387_CEIL] = 1;
17688   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17689   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17690   if (memory_operand (operands[0], VOIDmode))
17691     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17692                                      operands[2], operands[3]));
17693   else
17694     {
17695       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17696       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17697                                                  operands[2], operands[3],
17698                                                  operands[4]));
17699     }
17700   DONE;
17702   [(set_attr "type" "fistp")
17703    (set_attr "i387_cw" "ceil")
17704    (set_attr "mode" "<MODE>")])
17706 (define_insn "fistdi2_ceil"
17707   [(set (match_operand:DI 0 "memory_operand" "=m")
17708         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17709          UNSPEC_FIST_CEIL))
17710    (use (match_operand:HI 2 "memory_operand" "m"))
17711    (use (match_operand:HI 3 "memory_operand" "m"))
17712    (clobber (match_scratch:XF 4 "=&1f"))]
17713   "TARGET_USE_FANCY_MATH_387
17714    && flag_unsafe_math_optimizations"
17715   "* return output_fix_trunc (insn, operands, 0);"
17716   [(set_attr "type" "fistp")
17717    (set_attr "i387_cw" "ceil")
17718    (set_attr "mode" "DI")])
17720 (define_insn "fistdi2_ceil_with_temp"
17721   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17722         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17723          UNSPEC_FIST_CEIL))
17724    (use (match_operand:HI 2 "memory_operand" "m,m"))
17725    (use (match_operand:HI 3 "memory_operand" "m,m"))
17726    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17727    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17728   "TARGET_USE_FANCY_MATH_387
17729    && flag_unsafe_math_optimizations"
17730   "#"
17731   [(set_attr "type" "fistp")
17732    (set_attr "i387_cw" "ceil")
17733    (set_attr "mode" "DI")])
17735 (define_split 
17736   [(set (match_operand:DI 0 "register_operand" "")
17737         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17738          UNSPEC_FIST_CEIL))
17739    (use (match_operand:HI 2 "memory_operand" ""))
17740    (use (match_operand:HI 3 "memory_operand" ""))
17741    (clobber (match_operand:DI 4 "memory_operand" ""))
17742    (clobber (match_scratch 5 ""))]
17743   "reload_completed"
17744   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17745               (use (match_dup 2))
17746               (use (match_dup 3))
17747               (clobber (match_dup 5))])
17748    (set (match_dup 0) (match_dup 4))]
17749   "")
17751 (define_split 
17752   [(set (match_operand:DI 0 "memory_operand" "")
17753         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17754          UNSPEC_FIST_CEIL))
17755    (use (match_operand:HI 2 "memory_operand" ""))
17756    (use (match_operand:HI 3 "memory_operand" ""))
17757    (clobber (match_operand:DI 4 "memory_operand" ""))
17758    (clobber (match_scratch 5 ""))]
17759   "reload_completed"
17760   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17761               (use (match_dup 2))
17762               (use (match_dup 3))
17763               (clobber (match_dup 5))])]
17764   "")
17766 (define_insn "fist<mode>2_ceil"
17767   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17768         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17769          UNSPEC_FIST_CEIL))
17770    (use (match_operand:HI 2 "memory_operand" "m"))
17771    (use (match_operand:HI 3 "memory_operand" "m"))]
17772   "TARGET_USE_FANCY_MATH_387
17773    && flag_unsafe_math_optimizations"
17774   "* return output_fix_trunc (insn, operands, 0);"
17775   [(set_attr "type" "fistp")
17776    (set_attr "i387_cw" "ceil")
17777    (set_attr "mode" "<MODE>")])
17779 (define_insn "fist<mode>2_ceil_with_temp"
17780   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17781         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17782          UNSPEC_FIST_CEIL))
17783    (use (match_operand:HI 2 "memory_operand" "m,m"))
17784    (use (match_operand:HI 3 "memory_operand" "m,m"))
17785    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17786   "TARGET_USE_FANCY_MATH_387
17787    && flag_unsafe_math_optimizations"
17788   "#"
17789   [(set_attr "type" "fistp")
17790    (set_attr "i387_cw" "ceil")
17791    (set_attr "mode" "<MODE>")])
17793 (define_split 
17794   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17795         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17796          UNSPEC_FIST_CEIL))
17797    (use (match_operand:HI 2 "memory_operand" ""))
17798    (use (match_operand:HI 3 "memory_operand" ""))
17799    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17800   "reload_completed"
17801   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17802                                   UNSPEC_FIST_CEIL))
17803               (use (match_dup 2))
17804               (use (match_dup 3))])
17805    (set (match_dup 0) (match_dup 4))]
17806   "")
17808 (define_split 
17809   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17810         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17811          UNSPEC_FIST_CEIL))
17812    (use (match_operand:HI 2 "memory_operand" ""))
17813    (use (match_operand:HI 3 "memory_operand" ""))
17814    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17815   "reload_completed"
17816   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17817                                   UNSPEC_FIST_CEIL))
17818               (use (match_dup 2))
17819               (use (match_dup 3))])]
17820   "")
17822 (define_expand "lceil<mode>2"
17823   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17824                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17825                     UNSPEC_FIST_CEIL))
17826               (clobber (reg:CC FLAGS_REG))])]
17827   "TARGET_USE_FANCY_MATH_387
17828    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17829    && flag_unsafe_math_optimizations"
17830   "")
17832 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17833 (define_insn_and_split "frndintxf2_trunc"
17834   [(set (match_operand:XF 0 "register_operand" "=f")
17835         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17836          UNSPEC_FRNDINT_TRUNC))
17837    (clobber (reg:CC FLAGS_REG))]
17838   "TARGET_USE_FANCY_MATH_387
17839    && flag_unsafe_math_optimizations
17840    && !(reload_completed || reload_in_progress)"
17841   "#"
17842   "&& 1"
17843   [(const_int 0)]
17845   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17847   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17848   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17850   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17851                                         operands[2], operands[3]));
17852   DONE;
17854   [(set_attr "type" "frndint")
17855    (set_attr "i387_cw" "trunc")
17856    (set_attr "mode" "XF")])
17858 (define_insn "frndintxf2_trunc_i387"
17859   [(set (match_operand:XF 0 "register_operand" "=f")
17860         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17861          UNSPEC_FRNDINT_TRUNC))
17862    (use (match_operand:HI 2 "memory_operand" "m"))
17863    (use (match_operand:HI 3 "memory_operand" "m"))]
17864   "TARGET_USE_FANCY_MATH_387
17865    && flag_unsafe_math_optimizations"
17866   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17867   [(set_attr "type" "frndint")
17868    (set_attr "i387_cw" "trunc")
17869    (set_attr "mode" "XF")])
17871 (define_expand "btruncxf2"
17872   [(use (match_operand:XF 0 "register_operand" ""))
17873    (use (match_operand:XF 1 "register_operand" ""))]
17874   "TARGET_USE_FANCY_MATH_387
17875    && flag_unsafe_math_optimizations"
17877   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17878   DONE;
17881 (define_expand "btruncdf2"
17882   [(use (match_operand:DF 0 "register_operand" ""))
17883    (use (match_operand:DF 1 "register_operand" ""))]
17884   "TARGET_USE_FANCY_MATH_387
17885    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17886    && flag_unsafe_math_optimizations"
17888   rtx op0 = gen_reg_rtx (XFmode);
17889   rtx op1 = gen_reg_rtx (XFmode);
17891   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17892   emit_insn (gen_frndintxf2_trunc (op0, op1));
17894   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17895   DONE;
17898 (define_expand "btruncsf2"
17899   [(use (match_operand:SF 0 "register_operand" ""))
17900    (use (match_operand:SF 1 "register_operand" ""))]
17901   "TARGET_USE_FANCY_MATH_387
17902    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17903    && flag_unsafe_math_optimizations"
17905   rtx op0 = gen_reg_rtx (XFmode);
17906   rtx op1 = gen_reg_rtx (XFmode);
17908   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17909   emit_insn (gen_frndintxf2_trunc (op0, op1));
17911   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17912   DONE;
17915 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17916 (define_insn_and_split "frndintxf2_mask_pm"
17917   [(set (match_operand:XF 0 "register_operand" "=f")
17918         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17919          UNSPEC_FRNDINT_MASK_PM))
17920    (clobber (reg:CC FLAGS_REG))]
17921   "TARGET_USE_FANCY_MATH_387
17922    && flag_unsafe_math_optimizations
17923    && !(reload_completed || reload_in_progress)"
17924   "#"
17925   "&& 1"
17926   [(const_int 0)]
17928   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17930   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17931   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17933   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17934                                           operands[2], operands[3]));
17935   DONE;
17937   [(set_attr "type" "frndint")
17938    (set_attr "i387_cw" "mask_pm")
17939    (set_attr "mode" "XF")])
17941 (define_insn "frndintxf2_mask_pm_i387"
17942   [(set (match_operand:XF 0 "register_operand" "=f")
17943         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17944          UNSPEC_FRNDINT_MASK_PM))
17945    (use (match_operand:HI 2 "memory_operand" "m"))
17946    (use (match_operand:HI 3 "memory_operand" "m"))]
17947   "TARGET_USE_FANCY_MATH_387
17948    && flag_unsafe_math_optimizations"
17949   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17950   [(set_attr "type" "frndint")
17951    (set_attr "i387_cw" "mask_pm")
17952    (set_attr "mode" "XF")])
17954 (define_expand "nearbyintxf2"
17955   [(use (match_operand:XF 0 "register_operand" ""))
17956    (use (match_operand:XF 1 "register_operand" ""))]
17957   "TARGET_USE_FANCY_MATH_387
17958    && flag_unsafe_math_optimizations"
17960   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17962   DONE;
17965 (define_expand "nearbyintdf2"
17966   [(use (match_operand:DF 0 "register_operand" ""))
17967    (use (match_operand:DF 1 "register_operand" ""))]
17968   "TARGET_USE_FANCY_MATH_387
17969    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17970    && flag_unsafe_math_optimizations"
17972   rtx op0 = gen_reg_rtx (XFmode);
17973   rtx op1 = gen_reg_rtx (XFmode);
17975   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17976   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17978   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17979   DONE;
17982 (define_expand "nearbyintsf2"
17983   [(use (match_operand:SF 0 "register_operand" ""))
17984    (use (match_operand:SF 1 "register_operand" ""))]
17985   "TARGET_USE_FANCY_MATH_387
17986    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17987    && flag_unsafe_math_optimizations"
17989   rtx op0 = gen_reg_rtx (XFmode);
17990   rtx op1 = gen_reg_rtx (XFmode);
17992   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17993   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17995   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17996   DONE;
18000 ;; Block operation instructions
18002 (define_insn "cld"
18003  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18004  ""
18005  "cld"
18006   [(set_attr "type" "cld")])
18008 (define_expand "movmemsi"
18009   [(use (match_operand:BLK 0 "memory_operand" ""))
18010    (use (match_operand:BLK 1 "memory_operand" ""))
18011    (use (match_operand:SI 2 "nonmemory_operand" ""))
18012    (use (match_operand:SI 3 "const_int_operand" ""))]
18013   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18015  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18016    DONE;
18017  else
18018    FAIL;
18021 (define_expand "movmemdi"
18022   [(use (match_operand:BLK 0 "memory_operand" ""))
18023    (use (match_operand:BLK 1 "memory_operand" ""))
18024    (use (match_operand:DI 2 "nonmemory_operand" ""))
18025    (use (match_operand:DI 3 "const_int_operand" ""))]
18026   "TARGET_64BIT"
18028  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18029    DONE;
18030  else
18031    FAIL;
18034 ;; Most CPUs don't like single string operations
18035 ;; Handle this case here to simplify previous expander.
18037 (define_expand "strmov"
18038   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18039    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18040    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18041               (clobber (reg:CC FLAGS_REG))])
18042    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18043               (clobber (reg:CC FLAGS_REG))])]
18044   ""
18046   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18048   /* If .md ever supports :P for Pmode, these can be directly
18049      in the pattern above.  */
18050   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18051   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18053   if (TARGET_SINGLE_STRINGOP || optimize_size)
18054     {
18055       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18056                                       operands[2], operands[3],
18057                                       operands[5], operands[6]));
18058       DONE;
18059     }
18061   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18064 (define_expand "strmov_singleop"
18065   [(parallel [(set (match_operand 1 "memory_operand" "")
18066                    (match_operand 3 "memory_operand" ""))
18067               (set (match_operand 0 "register_operand" "")
18068                    (match_operand 4 "" ""))
18069               (set (match_operand 2 "register_operand" "")
18070                    (match_operand 5 "" ""))
18071               (use (reg:SI DIRFLAG_REG))])]
18072   "TARGET_SINGLE_STRINGOP || optimize_size"
18073   "")
18075 (define_insn "*strmovdi_rex_1"
18076   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18077         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18078    (set (match_operand:DI 0 "register_operand" "=D")
18079         (plus:DI (match_dup 2)
18080                  (const_int 8)))
18081    (set (match_operand:DI 1 "register_operand" "=S")
18082         (plus:DI (match_dup 3)
18083                  (const_int 8)))
18084    (use (reg:SI DIRFLAG_REG))]
18085   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18086   "movsq"
18087   [(set_attr "type" "str")
18088    (set_attr "mode" "DI")
18089    (set_attr "memory" "both")])
18091 (define_insn "*strmovsi_1"
18092   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18093         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18094    (set (match_operand:SI 0 "register_operand" "=D")
18095         (plus:SI (match_dup 2)
18096                  (const_int 4)))
18097    (set (match_operand:SI 1 "register_operand" "=S")
18098         (plus:SI (match_dup 3)
18099                  (const_int 4)))
18100    (use (reg:SI DIRFLAG_REG))]
18101   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18102   "{movsl|movsd}"
18103   [(set_attr "type" "str")
18104    (set_attr "mode" "SI")
18105    (set_attr "memory" "both")])
18107 (define_insn "*strmovsi_rex_1"
18108   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18109         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18110    (set (match_operand:DI 0 "register_operand" "=D")
18111         (plus:DI (match_dup 2)
18112                  (const_int 4)))
18113    (set (match_operand:DI 1 "register_operand" "=S")
18114         (plus:DI (match_dup 3)
18115                  (const_int 4)))
18116    (use (reg:SI DIRFLAG_REG))]
18117   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18118   "{movsl|movsd}"
18119   [(set_attr "type" "str")
18120    (set_attr "mode" "SI")
18121    (set_attr "memory" "both")])
18123 (define_insn "*strmovhi_1"
18124   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18125         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18126    (set (match_operand:SI 0 "register_operand" "=D")
18127         (plus:SI (match_dup 2)
18128                  (const_int 2)))
18129    (set (match_operand:SI 1 "register_operand" "=S")
18130         (plus:SI (match_dup 3)
18131                  (const_int 2)))
18132    (use (reg:SI DIRFLAG_REG))]
18133   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18134   "movsw"
18135   [(set_attr "type" "str")
18136    (set_attr "memory" "both")
18137    (set_attr "mode" "HI")])
18139 (define_insn "*strmovhi_rex_1"
18140   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18141         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18142    (set (match_operand:DI 0 "register_operand" "=D")
18143         (plus:DI (match_dup 2)
18144                  (const_int 2)))
18145    (set (match_operand:DI 1 "register_operand" "=S")
18146         (plus:DI (match_dup 3)
18147                  (const_int 2)))
18148    (use (reg:SI DIRFLAG_REG))]
18149   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18150   "movsw"
18151   [(set_attr "type" "str")
18152    (set_attr "memory" "both")
18153    (set_attr "mode" "HI")])
18155 (define_insn "*strmovqi_1"
18156   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18157         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18158    (set (match_operand:SI 0 "register_operand" "=D")
18159         (plus:SI (match_dup 2)
18160                  (const_int 1)))
18161    (set (match_operand:SI 1 "register_operand" "=S")
18162         (plus:SI (match_dup 3)
18163                  (const_int 1)))
18164    (use (reg:SI DIRFLAG_REG))]
18165   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18166   "movsb"
18167   [(set_attr "type" "str")
18168    (set_attr "memory" "both")
18169    (set_attr "mode" "QI")])
18171 (define_insn "*strmovqi_rex_1"
18172   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18173         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18174    (set (match_operand:DI 0 "register_operand" "=D")
18175         (plus:DI (match_dup 2)
18176                  (const_int 1)))
18177    (set (match_operand:DI 1 "register_operand" "=S")
18178         (plus:DI (match_dup 3)
18179                  (const_int 1)))
18180    (use (reg:SI DIRFLAG_REG))]
18181   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18182   "movsb"
18183   [(set_attr "type" "str")
18184    (set_attr "memory" "both")
18185    (set_attr "mode" "QI")])
18187 (define_expand "rep_mov"
18188   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18189               (set (match_operand 0 "register_operand" "")
18190                    (match_operand 5 "" ""))
18191               (set (match_operand 2 "register_operand" "")
18192                    (match_operand 6 "" ""))
18193               (set (match_operand 1 "memory_operand" "")
18194                    (match_operand 3 "memory_operand" ""))
18195               (use (match_dup 4))
18196               (use (reg:SI DIRFLAG_REG))])]
18197   ""
18198   "")
18200 (define_insn "*rep_movdi_rex64"
18201   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18202    (set (match_operand:DI 0 "register_operand" "=D") 
18203         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18204                             (const_int 3))
18205                  (match_operand:DI 3 "register_operand" "0")))
18206    (set (match_operand:DI 1 "register_operand" "=S") 
18207         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18208                  (match_operand:DI 4 "register_operand" "1")))
18209    (set (mem:BLK (match_dup 3))
18210         (mem:BLK (match_dup 4)))
18211    (use (match_dup 5))
18212    (use (reg:SI DIRFLAG_REG))]
18213   "TARGET_64BIT"
18214   "{rep\;movsq|rep movsq}"
18215   [(set_attr "type" "str")
18216    (set_attr "prefix_rep" "1")
18217    (set_attr "memory" "both")
18218    (set_attr "mode" "DI")])
18220 (define_insn "*rep_movsi"
18221   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18222    (set (match_operand:SI 0 "register_operand" "=D") 
18223         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18224                             (const_int 2))
18225                  (match_operand:SI 3 "register_operand" "0")))
18226    (set (match_operand:SI 1 "register_operand" "=S") 
18227         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18228                  (match_operand:SI 4 "register_operand" "1")))
18229    (set (mem:BLK (match_dup 3))
18230         (mem:BLK (match_dup 4)))
18231    (use (match_dup 5))
18232    (use (reg:SI DIRFLAG_REG))]
18233   "!TARGET_64BIT"
18234   "{rep\;movsl|rep movsd}"
18235   [(set_attr "type" "str")
18236    (set_attr "prefix_rep" "1")
18237    (set_attr "memory" "both")
18238    (set_attr "mode" "SI")])
18240 (define_insn "*rep_movsi_rex64"
18241   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18242    (set (match_operand:DI 0 "register_operand" "=D") 
18243         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18244                             (const_int 2))
18245                  (match_operand:DI 3 "register_operand" "0")))
18246    (set (match_operand:DI 1 "register_operand" "=S") 
18247         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18248                  (match_operand:DI 4 "register_operand" "1")))
18249    (set (mem:BLK (match_dup 3))
18250         (mem:BLK (match_dup 4)))
18251    (use (match_dup 5))
18252    (use (reg:SI DIRFLAG_REG))]
18253   "TARGET_64BIT"
18254   "{rep\;movsl|rep movsd}"
18255   [(set_attr "type" "str")
18256    (set_attr "prefix_rep" "1")
18257    (set_attr "memory" "both")
18258    (set_attr "mode" "SI")])
18260 (define_insn "*rep_movqi"
18261   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18262    (set (match_operand:SI 0 "register_operand" "=D") 
18263         (plus:SI (match_operand:SI 3 "register_operand" "0")
18264                  (match_operand:SI 5 "register_operand" "2")))
18265    (set (match_operand:SI 1 "register_operand" "=S") 
18266         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18267    (set (mem:BLK (match_dup 3))
18268         (mem:BLK (match_dup 4)))
18269    (use (match_dup 5))
18270    (use (reg:SI DIRFLAG_REG))]
18271   "!TARGET_64BIT"
18272   "{rep\;movsb|rep movsb}"
18273   [(set_attr "type" "str")
18274    (set_attr "prefix_rep" "1")
18275    (set_attr "memory" "both")
18276    (set_attr "mode" "SI")])
18278 (define_insn "*rep_movqi_rex64"
18279   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18280    (set (match_operand:DI 0 "register_operand" "=D") 
18281         (plus:DI (match_operand:DI 3 "register_operand" "0")
18282                  (match_operand:DI 5 "register_operand" "2")))
18283    (set (match_operand:DI 1 "register_operand" "=S") 
18284         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18285    (set (mem:BLK (match_dup 3))
18286         (mem:BLK (match_dup 4)))
18287    (use (match_dup 5))
18288    (use (reg:SI DIRFLAG_REG))]
18289   "TARGET_64BIT"
18290   "{rep\;movsb|rep movsb}"
18291   [(set_attr "type" "str")
18292    (set_attr "prefix_rep" "1")
18293    (set_attr "memory" "both")
18294    (set_attr "mode" "SI")])
18296 (define_expand "setmemsi"
18297    [(use (match_operand:BLK 0 "memory_operand" ""))
18298     (use (match_operand:SI 1 "nonmemory_operand" ""))
18299     (use (match_operand 2 "const_int_operand" ""))
18300     (use (match_operand 3 "const_int_operand" ""))]
18301   ""
18303  /* If value to set is not zero, use the library routine.  */
18304  if (operands[2] != const0_rtx)
18305    FAIL;
18307  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18308    DONE;
18309  else
18310    FAIL;
18313 (define_expand "setmemdi"
18314    [(use (match_operand:BLK 0 "memory_operand" ""))
18315     (use (match_operand:DI 1 "nonmemory_operand" ""))
18316     (use (match_operand 2 "const_int_operand" ""))
18317     (use (match_operand 3 "const_int_operand" ""))]
18318   "TARGET_64BIT"
18320  /* If value to set is not zero, use the library routine.  */
18321  if (operands[2] != const0_rtx)
18322    FAIL;
18324  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18325    DONE;
18326  else
18327    FAIL;
18330 ;; Most CPUs don't like single string operations
18331 ;; Handle this case here to simplify previous expander.
18333 (define_expand "strset"
18334   [(set (match_operand 1 "memory_operand" "")
18335         (match_operand 2 "register_operand" ""))
18336    (parallel [(set (match_operand 0 "register_operand" "")
18337                    (match_dup 3))
18338               (clobber (reg:CC FLAGS_REG))])]
18339   ""
18341   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18342     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18344   /* If .md ever supports :P for Pmode, this can be directly
18345      in the pattern above.  */
18346   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18347                               GEN_INT (GET_MODE_SIZE (GET_MODE
18348                                                       (operands[2]))));
18349   if (TARGET_SINGLE_STRINGOP || optimize_size)
18350     {
18351       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18352                                       operands[3]));
18353       DONE;
18354     }
18357 (define_expand "strset_singleop"
18358   [(parallel [(set (match_operand 1 "memory_operand" "")
18359                    (match_operand 2 "register_operand" ""))
18360               (set (match_operand 0 "register_operand" "")
18361                    (match_operand 3 "" ""))
18362               (use (reg:SI DIRFLAG_REG))])]
18363   "TARGET_SINGLE_STRINGOP || optimize_size"
18364   "")
18366 (define_insn "*strsetdi_rex_1"
18367   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18368         (match_operand:DI 2 "register_operand" "a"))
18369    (set (match_operand:DI 0 "register_operand" "=D")
18370         (plus:DI (match_dup 1)
18371                  (const_int 8)))
18372    (use (reg:SI DIRFLAG_REG))]
18373   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18374   "stosq"
18375   [(set_attr "type" "str")
18376    (set_attr "memory" "store")
18377    (set_attr "mode" "DI")])
18379 (define_insn "*strsetsi_1"
18380   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18381         (match_operand:SI 2 "register_operand" "a"))
18382    (set (match_operand:SI 0 "register_operand" "=D")
18383         (plus:SI (match_dup 1)
18384                  (const_int 4)))
18385    (use (reg:SI DIRFLAG_REG))]
18386   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18387   "{stosl|stosd}"
18388   [(set_attr "type" "str")
18389    (set_attr "memory" "store")
18390    (set_attr "mode" "SI")])
18392 (define_insn "*strsetsi_rex_1"
18393   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18394         (match_operand:SI 2 "register_operand" "a"))
18395    (set (match_operand:DI 0 "register_operand" "=D")
18396         (plus:DI (match_dup 1)
18397                  (const_int 4)))
18398    (use (reg:SI DIRFLAG_REG))]
18399   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18400   "{stosl|stosd}"
18401   [(set_attr "type" "str")
18402    (set_attr "memory" "store")
18403    (set_attr "mode" "SI")])
18405 (define_insn "*strsethi_1"
18406   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18407         (match_operand:HI 2 "register_operand" "a"))
18408    (set (match_operand:SI 0 "register_operand" "=D")
18409         (plus:SI (match_dup 1)
18410                  (const_int 2)))
18411    (use (reg:SI DIRFLAG_REG))]
18412   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18413   "stosw"
18414   [(set_attr "type" "str")
18415    (set_attr "memory" "store")
18416    (set_attr "mode" "HI")])
18418 (define_insn "*strsethi_rex_1"
18419   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18420         (match_operand:HI 2 "register_operand" "a"))
18421    (set (match_operand:DI 0 "register_operand" "=D")
18422         (plus:DI (match_dup 1)
18423                  (const_int 2)))
18424    (use (reg:SI DIRFLAG_REG))]
18425   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18426   "stosw"
18427   [(set_attr "type" "str")
18428    (set_attr "memory" "store")
18429    (set_attr "mode" "HI")])
18431 (define_insn "*strsetqi_1"
18432   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18433         (match_operand:QI 2 "register_operand" "a"))
18434    (set (match_operand:SI 0 "register_operand" "=D")
18435         (plus:SI (match_dup 1)
18436                  (const_int 1)))
18437    (use (reg:SI DIRFLAG_REG))]
18438   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18439   "stosb"
18440   [(set_attr "type" "str")
18441    (set_attr "memory" "store")
18442    (set_attr "mode" "QI")])
18444 (define_insn "*strsetqi_rex_1"
18445   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18446         (match_operand:QI 2 "register_operand" "a"))
18447    (set (match_operand:DI 0 "register_operand" "=D")
18448         (plus:DI (match_dup 1)
18449                  (const_int 1)))
18450    (use (reg:SI DIRFLAG_REG))]
18451   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18452   "stosb"
18453   [(set_attr "type" "str")
18454    (set_attr "memory" "store")
18455    (set_attr "mode" "QI")])
18457 (define_expand "rep_stos"
18458   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18459               (set (match_operand 0 "register_operand" "")
18460                    (match_operand 4 "" ""))
18461               (set (match_operand 2 "memory_operand" "") (const_int 0))
18462               (use (match_operand 3 "register_operand" ""))
18463               (use (match_dup 1))
18464               (use (reg:SI DIRFLAG_REG))])]
18465   ""
18466   "")
18468 (define_insn "*rep_stosdi_rex64"
18469   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18470    (set (match_operand:DI 0 "register_operand" "=D") 
18471         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18472                             (const_int 3))
18473                  (match_operand:DI 3 "register_operand" "0")))
18474    (set (mem:BLK (match_dup 3))
18475         (const_int 0))
18476    (use (match_operand:DI 2 "register_operand" "a"))
18477    (use (match_dup 4))
18478    (use (reg:SI DIRFLAG_REG))]
18479   "TARGET_64BIT"
18480   "{rep\;stosq|rep stosq}"
18481   [(set_attr "type" "str")
18482    (set_attr "prefix_rep" "1")
18483    (set_attr "memory" "store")
18484    (set_attr "mode" "DI")])
18486 (define_insn "*rep_stossi"
18487   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18488    (set (match_operand:SI 0 "register_operand" "=D") 
18489         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18490                             (const_int 2))
18491                  (match_operand:SI 3 "register_operand" "0")))
18492    (set (mem:BLK (match_dup 3))
18493         (const_int 0))
18494    (use (match_operand:SI 2 "register_operand" "a"))
18495    (use (match_dup 4))
18496    (use (reg:SI DIRFLAG_REG))]
18497   "!TARGET_64BIT"
18498   "{rep\;stosl|rep stosd}"
18499   [(set_attr "type" "str")
18500    (set_attr "prefix_rep" "1")
18501    (set_attr "memory" "store")
18502    (set_attr "mode" "SI")])
18504 (define_insn "*rep_stossi_rex64"
18505   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18506    (set (match_operand:DI 0 "register_operand" "=D") 
18507         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18508                             (const_int 2))
18509                  (match_operand:DI 3 "register_operand" "0")))
18510    (set (mem:BLK (match_dup 3))
18511         (const_int 0))
18512    (use (match_operand:SI 2 "register_operand" "a"))
18513    (use (match_dup 4))
18514    (use (reg:SI DIRFLAG_REG))]
18515   "TARGET_64BIT"
18516   "{rep\;stosl|rep stosd}"
18517   [(set_attr "type" "str")
18518    (set_attr "prefix_rep" "1")
18519    (set_attr "memory" "store")
18520    (set_attr "mode" "SI")])
18522 (define_insn "*rep_stosqi"
18523   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18524    (set (match_operand:SI 0 "register_operand" "=D") 
18525         (plus:SI (match_operand:SI 3 "register_operand" "0")
18526                  (match_operand:SI 4 "register_operand" "1")))
18527    (set (mem:BLK (match_dup 3))
18528         (const_int 0))
18529    (use (match_operand:QI 2 "register_operand" "a"))
18530    (use (match_dup 4))
18531    (use (reg:SI DIRFLAG_REG))]
18532   "!TARGET_64BIT"
18533   "{rep\;stosb|rep stosb}"
18534   [(set_attr "type" "str")
18535    (set_attr "prefix_rep" "1")
18536    (set_attr "memory" "store")
18537    (set_attr "mode" "QI")])
18539 (define_insn "*rep_stosqi_rex64"
18540   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18541    (set (match_operand:DI 0 "register_operand" "=D") 
18542         (plus:DI (match_operand:DI 3 "register_operand" "0")
18543                  (match_operand:DI 4 "register_operand" "1")))
18544    (set (mem:BLK (match_dup 3))
18545         (const_int 0))
18546    (use (match_operand:QI 2 "register_operand" "a"))
18547    (use (match_dup 4))
18548    (use (reg:SI DIRFLAG_REG))]
18549   "TARGET_64BIT"
18550   "{rep\;stosb|rep stosb}"
18551   [(set_attr "type" "str")
18552    (set_attr "prefix_rep" "1")
18553    (set_attr "memory" "store")
18554    (set_attr "mode" "QI")])
18556 (define_expand "cmpstrnsi"
18557   [(set (match_operand:SI 0 "register_operand" "")
18558         (compare:SI (match_operand:BLK 1 "general_operand" "")
18559                     (match_operand:BLK 2 "general_operand" "")))
18560    (use (match_operand 3 "general_operand" ""))
18561    (use (match_operand 4 "immediate_operand" ""))]
18562   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18564   rtx addr1, addr2, out, outlow, count, countreg, align;
18566   /* Can't use this if the user has appropriated esi or edi.  */
18567   if (global_regs[4] || global_regs[5])
18568     FAIL;
18570   out = operands[0];
18571   if (GET_CODE (out) != REG)
18572     out = gen_reg_rtx (SImode);
18574   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18575   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18576   if (addr1 != XEXP (operands[1], 0))
18577     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18578   if (addr2 != XEXP (operands[2], 0))
18579     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18581   count = operands[3];
18582   countreg = ix86_zero_extend_to_Pmode (count);
18584   /* %%% Iff we are testing strict equality, we can use known alignment
18585      to good advantage.  This may be possible with combine, particularly
18586      once cc0 is dead.  */
18587   align = operands[4];
18589   emit_insn (gen_cld ());
18590   if (GET_CODE (count) == CONST_INT)
18591     {
18592       if (INTVAL (count) == 0)
18593         {
18594           emit_move_insn (operands[0], const0_rtx);
18595           DONE;
18596         }
18597       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18598                                      operands[1], operands[2]));
18599     }
18600   else
18601     {
18602       if (TARGET_64BIT)
18603         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18604       else
18605         emit_insn (gen_cmpsi_1 (countreg, countreg));
18606       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18607                                   operands[1], operands[2]));
18608     }
18610   outlow = gen_lowpart (QImode, out);
18611   emit_insn (gen_cmpintqi (outlow));
18612   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18614   if (operands[0] != out)
18615     emit_move_insn (operands[0], out);
18617   DONE;
18620 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18622 (define_expand "cmpintqi"
18623   [(set (match_dup 1)
18624         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18625    (set (match_dup 2)
18626         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18627    (parallel [(set (match_operand:QI 0 "register_operand" "")
18628                    (minus:QI (match_dup 1)
18629                              (match_dup 2)))
18630               (clobber (reg:CC FLAGS_REG))])]
18631   ""
18632   "operands[1] = gen_reg_rtx (QImode);
18633    operands[2] = gen_reg_rtx (QImode);")
18635 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18636 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18638 (define_expand "cmpstrnqi_nz_1"
18639   [(parallel [(set (reg:CC FLAGS_REG)
18640                    (compare:CC (match_operand 4 "memory_operand" "")
18641                                (match_operand 5 "memory_operand" "")))
18642               (use (match_operand 2 "register_operand" ""))
18643               (use (match_operand:SI 3 "immediate_operand" ""))
18644               (use (reg:SI DIRFLAG_REG))
18645               (clobber (match_operand 0 "register_operand" ""))
18646               (clobber (match_operand 1 "register_operand" ""))
18647               (clobber (match_dup 2))])]
18648   ""
18649   "")
18651 (define_insn "*cmpstrnqi_nz_1"
18652   [(set (reg:CC FLAGS_REG)
18653         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18654                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18655    (use (match_operand:SI 6 "register_operand" "2"))
18656    (use (match_operand:SI 3 "immediate_operand" "i"))
18657    (use (reg:SI DIRFLAG_REG))
18658    (clobber (match_operand:SI 0 "register_operand" "=S"))
18659    (clobber (match_operand:SI 1 "register_operand" "=D"))
18660    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18661   "!TARGET_64BIT"
18662   "repz{\;| }cmpsb"
18663   [(set_attr "type" "str")
18664    (set_attr "mode" "QI")
18665    (set_attr "prefix_rep" "1")])
18667 (define_insn "*cmpstrnqi_nz_rex_1"
18668   [(set (reg:CC FLAGS_REG)
18669         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18670                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18671    (use (match_operand:DI 6 "register_operand" "2"))
18672    (use (match_operand:SI 3 "immediate_operand" "i"))
18673    (use (reg:SI DIRFLAG_REG))
18674    (clobber (match_operand:DI 0 "register_operand" "=S"))
18675    (clobber (match_operand:DI 1 "register_operand" "=D"))
18676    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18677   "TARGET_64BIT"
18678   "repz{\;| }cmpsb"
18679   [(set_attr "type" "str")
18680    (set_attr "mode" "QI")
18681    (set_attr "prefix_rep" "1")])
18683 ;; The same, but the count is not known to not be zero.
18685 (define_expand "cmpstrnqi_1"
18686   [(parallel [(set (reg:CC FLAGS_REG)
18687                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18688                                      (const_int 0))
18689                   (compare:CC (match_operand 4 "memory_operand" "")
18690                               (match_operand 5 "memory_operand" ""))
18691                   (const_int 0)))
18692               (use (match_operand:SI 3 "immediate_operand" ""))
18693               (use (reg:CC FLAGS_REG))
18694               (use (reg:SI DIRFLAG_REG))
18695               (clobber (match_operand 0 "register_operand" ""))
18696               (clobber (match_operand 1 "register_operand" ""))
18697               (clobber (match_dup 2))])]
18698   ""
18699   "")
18701 (define_insn "*cmpstrnqi_1"
18702   [(set (reg:CC FLAGS_REG)
18703         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18704                              (const_int 0))
18705           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18706                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18707           (const_int 0)))
18708    (use (match_operand:SI 3 "immediate_operand" "i"))
18709    (use (reg:CC FLAGS_REG))
18710    (use (reg:SI DIRFLAG_REG))
18711    (clobber (match_operand:SI 0 "register_operand" "=S"))
18712    (clobber (match_operand:SI 1 "register_operand" "=D"))
18713    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18714   "!TARGET_64BIT"
18715   "repz{\;| }cmpsb"
18716   [(set_attr "type" "str")
18717    (set_attr "mode" "QI")
18718    (set_attr "prefix_rep" "1")])
18720 (define_insn "*cmpstrnqi_rex_1"
18721   [(set (reg:CC FLAGS_REG)
18722         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18723                              (const_int 0))
18724           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18725                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18726           (const_int 0)))
18727    (use (match_operand:SI 3 "immediate_operand" "i"))
18728    (use (reg:CC FLAGS_REG))
18729    (use (reg:SI DIRFLAG_REG))
18730    (clobber (match_operand:DI 0 "register_operand" "=S"))
18731    (clobber (match_operand:DI 1 "register_operand" "=D"))
18732    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18733   "TARGET_64BIT"
18734   "repz{\;| }cmpsb"
18735   [(set_attr "type" "str")
18736    (set_attr "mode" "QI")
18737    (set_attr "prefix_rep" "1")])
18739 (define_expand "strlensi"
18740   [(set (match_operand:SI 0 "register_operand" "")
18741         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18742                     (match_operand:QI 2 "immediate_operand" "")
18743                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18744   ""
18746  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18747    DONE;
18748  else
18749    FAIL;
18752 (define_expand "strlendi"
18753   [(set (match_operand:DI 0 "register_operand" "")
18754         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18755                     (match_operand:QI 2 "immediate_operand" "")
18756                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18757   ""
18759  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18760    DONE;
18761  else
18762    FAIL;
18765 (define_expand "strlenqi_1"
18766   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18767               (use (reg:SI DIRFLAG_REG))
18768               (clobber (match_operand 1 "register_operand" ""))
18769               (clobber (reg:CC FLAGS_REG))])]
18770   ""
18771   "")
18773 (define_insn "*strlenqi_1"
18774   [(set (match_operand:SI 0 "register_operand" "=&c")
18775         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18776                     (match_operand:QI 2 "register_operand" "a")
18777                     (match_operand:SI 3 "immediate_operand" "i")
18778                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18779    (use (reg:SI DIRFLAG_REG))
18780    (clobber (match_operand:SI 1 "register_operand" "=D"))
18781    (clobber (reg:CC FLAGS_REG))]
18782   "!TARGET_64BIT"
18783   "repnz{\;| }scasb"
18784   [(set_attr "type" "str")
18785    (set_attr "mode" "QI")
18786    (set_attr "prefix_rep" "1")])
18788 (define_insn "*strlenqi_rex_1"
18789   [(set (match_operand:DI 0 "register_operand" "=&c")
18790         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18791                     (match_operand:QI 2 "register_operand" "a")
18792                     (match_operand:DI 3 "immediate_operand" "i")
18793                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18794    (use (reg:SI DIRFLAG_REG))
18795    (clobber (match_operand:DI 1 "register_operand" "=D"))
18796    (clobber (reg:CC FLAGS_REG))]
18797   "TARGET_64BIT"
18798   "repnz{\;| }scasb"
18799   [(set_attr "type" "str")
18800    (set_attr "mode" "QI")
18801    (set_attr "prefix_rep" "1")])
18803 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18804 ;; handled in combine, but it is not currently up to the task.
18805 ;; When used for their truth value, the cmpstrn* expanders generate
18806 ;; code like this:
18808 ;;   repz cmpsb
18809 ;;   seta       %al
18810 ;;   setb       %dl
18811 ;;   cmpb       %al, %dl
18812 ;;   jcc        label
18814 ;; The intermediate three instructions are unnecessary.
18816 ;; This one handles cmpstrn*_nz_1...
18817 (define_peephole2
18818   [(parallel[
18819      (set (reg:CC FLAGS_REG)
18820           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18821                       (mem:BLK (match_operand 5 "register_operand" ""))))
18822      (use (match_operand 6 "register_operand" ""))
18823      (use (match_operand:SI 3 "immediate_operand" ""))
18824      (use (reg:SI DIRFLAG_REG))
18825      (clobber (match_operand 0 "register_operand" ""))
18826      (clobber (match_operand 1 "register_operand" ""))
18827      (clobber (match_operand 2 "register_operand" ""))])
18828    (set (match_operand:QI 7 "register_operand" "")
18829         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18830    (set (match_operand:QI 8 "register_operand" "")
18831         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18832    (set (reg FLAGS_REG)
18833         (compare (match_dup 7) (match_dup 8)))
18834   ]
18835   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18836   [(parallel[
18837      (set (reg:CC FLAGS_REG)
18838           (compare:CC (mem:BLK (match_dup 4))
18839                       (mem:BLK (match_dup 5))))
18840      (use (match_dup 6))
18841      (use (match_dup 3))
18842      (use (reg:SI DIRFLAG_REG))
18843      (clobber (match_dup 0))
18844      (clobber (match_dup 1))
18845      (clobber (match_dup 2))])]
18846   "")
18848 ;; ...and this one handles cmpstrn*_1.
18849 (define_peephole2
18850   [(parallel[
18851      (set (reg:CC FLAGS_REG)
18852           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18853                                (const_int 0))
18854             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18855                         (mem:BLK (match_operand 5 "register_operand" "")))
18856             (const_int 0)))
18857      (use (match_operand:SI 3 "immediate_operand" ""))
18858      (use (reg:CC FLAGS_REG))
18859      (use (reg:SI DIRFLAG_REG))
18860      (clobber (match_operand 0 "register_operand" ""))
18861      (clobber (match_operand 1 "register_operand" ""))
18862      (clobber (match_operand 2 "register_operand" ""))])
18863    (set (match_operand:QI 7 "register_operand" "")
18864         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18865    (set (match_operand:QI 8 "register_operand" "")
18866         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18867    (set (reg FLAGS_REG)
18868         (compare (match_dup 7) (match_dup 8)))
18869   ]
18870   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18871   [(parallel[
18872      (set (reg:CC FLAGS_REG)
18873           (if_then_else:CC (ne (match_dup 6)
18874                                (const_int 0))
18875             (compare:CC (mem:BLK (match_dup 4))
18876                         (mem:BLK (match_dup 5)))
18877             (const_int 0)))
18878      (use (match_dup 3))
18879      (use (reg:CC FLAGS_REG))
18880      (use (reg:SI DIRFLAG_REG))
18881      (clobber (match_dup 0))
18882      (clobber (match_dup 1))
18883      (clobber (match_dup 2))])]
18884   "")
18888 ;; Conditional move instructions.
18890 (define_expand "movdicc"
18891   [(set (match_operand:DI 0 "register_operand" "")
18892         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18893                          (match_operand:DI 2 "general_operand" "")
18894                          (match_operand:DI 3 "general_operand" "")))]
18895   "TARGET_64BIT"
18896   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18898 (define_insn "x86_movdicc_0_m1_rex64"
18899   [(set (match_operand:DI 0 "register_operand" "=r")
18900         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18901           (const_int -1)
18902           (const_int 0)))
18903    (clobber (reg:CC FLAGS_REG))]
18904   "TARGET_64BIT"
18905   "sbb{q}\t%0, %0"
18906   ; Since we don't have the proper number of operands for an alu insn,
18907   ; fill in all the blanks.
18908   [(set_attr "type" "alu")
18909    (set_attr "pent_pair" "pu")
18910    (set_attr "memory" "none")
18911    (set_attr "imm_disp" "false")
18912    (set_attr "mode" "DI")
18913    (set_attr "length_immediate" "0")])
18915 (define_insn "*movdicc_c_rex64"
18916   [(set (match_operand:DI 0 "register_operand" "=r,r")
18917         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18918                                 [(reg FLAGS_REG) (const_int 0)])
18919                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18920                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18921   "TARGET_64BIT && TARGET_CMOVE
18922    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18923   "@
18924    cmov%O2%C1\t{%2, %0|%0, %2}
18925    cmov%O2%c1\t{%3, %0|%0, %3}"
18926   [(set_attr "type" "icmov")
18927    (set_attr "mode" "DI")])
18929 (define_expand "movsicc"
18930   [(set (match_operand:SI 0 "register_operand" "")
18931         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18932                          (match_operand:SI 2 "general_operand" "")
18933                          (match_operand:SI 3 "general_operand" "")))]
18934   ""
18935   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18937 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18938 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18939 ;; So just document what we're doing explicitly.
18941 (define_insn "x86_movsicc_0_m1"
18942   [(set (match_operand:SI 0 "register_operand" "=r")
18943         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18944           (const_int -1)
18945           (const_int 0)))
18946    (clobber (reg:CC FLAGS_REG))]
18947   ""
18948   "sbb{l}\t%0, %0"
18949   ; Since we don't have the proper number of operands for an alu insn,
18950   ; fill in all the blanks.
18951   [(set_attr "type" "alu")
18952    (set_attr "pent_pair" "pu")
18953    (set_attr "memory" "none")
18954    (set_attr "imm_disp" "false")
18955    (set_attr "mode" "SI")
18956    (set_attr "length_immediate" "0")])
18958 (define_insn "*movsicc_noc"
18959   [(set (match_operand:SI 0 "register_operand" "=r,r")
18960         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18961                                 [(reg FLAGS_REG) (const_int 0)])
18962                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18963                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18964   "TARGET_CMOVE
18965    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18966   "@
18967    cmov%O2%C1\t{%2, %0|%0, %2}
18968    cmov%O2%c1\t{%3, %0|%0, %3}"
18969   [(set_attr "type" "icmov")
18970    (set_attr "mode" "SI")])
18972 (define_expand "movhicc"
18973   [(set (match_operand:HI 0 "register_operand" "")
18974         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18975                          (match_operand:HI 2 "general_operand" "")
18976                          (match_operand:HI 3 "general_operand" "")))]
18977   "TARGET_HIMODE_MATH"
18978   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18980 (define_insn "*movhicc_noc"
18981   [(set (match_operand:HI 0 "register_operand" "=r,r")
18982         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18983                                 [(reg FLAGS_REG) (const_int 0)])
18984                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18985                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18986   "TARGET_CMOVE
18987    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18988   "@
18989    cmov%O2%C1\t{%2, %0|%0, %2}
18990    cmov%O2%c1\t{%3, %0|%0, %3}"
18991   [(set_attr "type" "icmov")
18992    (set_attr "mode" "HI")])
18994 (define_expand "movqicc"
18995   [(set (match_operand:QI 0 "register_operand" "")
18996         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18997                          (match_operand:QI 2 "general_operand" "")
18998                          (match_operand:QI 3 "general_operand" "")))]
18999   "TARGET_QIMODE_MATH"
19000   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19002 (define_insn_and_split "*movqicc_noc"
19003   [(set (match_operand:QI 0 "register_operand" "=r,r")
19004         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
19005                                 [(match_operand 4 "flags_reg_operand" "")
19006                                  (const_int 0)])
19007                       (match_operand:QI 2 "register_operand" "r,0")
19008                       (match_operand:QI 3 "register_operand" "0,r")))]
19009   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19010   "#"
19011   "&& reload_completed"
19012   [(set (match_dup 0)
19013         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19014                       (match_dup 2)
19015                       (match_dup 3)))]
19016   "operands[0] = gen_lowpart (SImode, operands[0]);
19017    operands[2] = gen_lowpart (SImode, operands[2]);
19018    operands[3] = gen_lowpart (SImode, operands[3]);"
19019   [(set_attr "type" "icmov")
19020    (set_attr "mode" "SI")])
19022 (define_expand "movsfcc"
19023   [(set (match_operand:SF 0 "register_operand" "")
19024         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19025                          (match_operand:SF 2 "register_operand" "")
19026                          (match_operand:SF 3 "register_operand" "")))]
19027   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19028   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19030 (define_insn "*movsfcc_1_387"
19031   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19032         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19033                                 [(reg FLAGS_REG) (const_int 0)])
19034                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19035                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19036   "TARGET_80387 && TARGET_CMOVE
19037    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19038   "@
19039    fcmov%F1\t{%2, %0|%0, %2}
19040    fcmov%f1\t{%3, %0|%0, %3}
19041    cmov%O2%C1\t{%2, %0|%0, %2}
19042    cmov%O2%c1\t{%3, %0|%0, %3}"
19043   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19044    (set_attr "mode" "SF,SF,SI,SI")])
19046 (define_expand "movdfcc"
19047   [(set (match_operand:DF 0 "register_operand" "")
19048         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19049                          (match_operand:DF 2 "register_operand" "")
19050                          (match_operand:DF 3 "register_operand" "")))]
19051   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19052   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19054 (define_insn "*movdfcc_1"
19055   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19056         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19057                                 [(reg FLAGS_REG) (const_int 0)])
19058                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19059                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19060   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19061    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19062   "@
19063    fcmov%F1\t{%2, %0|%0, %2}
19064    fcmov%f1\t{%3, %0|%0, %3}
19065    #
19066    #"
19067   [(set_attr "type" "fcmov,fcmov,multi,multi")
19068    (set_attr "mode" "DF")])
19070 (define_insn "*movdfcc_1_rex64"
19071   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19072         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19073                                 [(reg FLAGS_REG) (const_int 0)])
19074                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19075                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19076   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19077    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19078   "@
19079    fcmov%F1\t{%2, %0|%0, %2}
19080    fcmov%f1\t{%3, %0|%0, %3}
19081    cmov%O2%C1\t{%2, %0|%0, %2}
19082    cmov%O2%c1\t{%3, %0|%0, %3}"
19083   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19084    (set_attr "mode" "DF")])
19086 (define_split
19087   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19088         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19089                                 [(match_operand 4 "flags_reg_operand" "")
19090                                  (const_int 0)])
19091                       (match_operand:DF 2 "nonimmediate_operand" "")
19092                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19093   "!TARGET_64BIT && reload_completed"
19094   [(set (match_dup 2)
19095         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19096                       (match_dup 5)
19097                       (match_dup 7)))
19098    (set (match_dup 3)
19099         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19100                       (match_dup 6)
19101                       (match_dup 8)))]
19102   "split_di (operands+2, 1, operands+5, operands+6);
19103    split_di (operands+3, 1, operands+7, operands+8);
19104    split_di (operands, 1, operands+2, operands+3);")
19106 (define_expand "movxfcc"
19107   [(set (match_operand:XF 0 "register_operand" "")
19108         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19109                          (match_operand:XF 2 "register_operand" "")
19110                          (match_operand:XF 3 "register_operand" "")))]
19111   "TARGET_80387 && TARGET_CMOVE"
19112   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19114 (define_insn "*movxfcc_1"
19115   [(set (match_operand:XF 0 "register_operand" "=f,f")
19116         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19117                                 [(reg FLAGS_REG) (const_int 0)])
19118                       (match_operand:XF 2 "register_operand" "f,0")
19119                       (match_operand:XF 3 "register_operand" "0,f")))]
19120   "TARGET_80387 && TARGET_CMOVE"
19121   "@
19122    fcmov%F1\t{%2, %0|%0, %2}
19123    fcmov%f1\t{%3, %0|%0, %3}"
19124   [(set_attr "type" "fcmov")
19125    (set_attr "mode" "XF")])
19127 ;; These versions of the min/max patterns are intentionally ignorant of
19128 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19129 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19130 ;; are undefined in this condition, we're certain this is correct.
19132 (define_insn "sminsf3"
19133   [(set (match_operand:SF 0 "register_operand" "=x")
19134         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19135                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19136   "TARGET_SSE_MATH"
19137   "minss\t{%2, %0|%0, %2}"
19138   [(set_attr "type" "sseadd")
19139    (set_attr "mode" "SF")])
19141 (define_insn "smaxsf3"
19142   [(set (match_operand:SF 0 "register_operand" "=x")
19143         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19144                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19145   "TARGET_SSE_MATH"
19146   "maxss\t{%2, %0|%0, %2}"
19147   [(set_attr "type" "sseadd")
19148    (set_attr "mode" "SF")])
19150 (define_insn "smindf3"
19151   [(set (match_operand:DF 0 "register_operand" "=x")
19152         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19153                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19154   "TARGET_SSE2 && TARGET_SSE_MATH"
19155   "minsd\t{%2, %0|%0, %2}"
19156   [(set_attr "type" "sseadd")
19157    (set_attr "mode" "DF")])
19159 (define_insn "smaxdf3"
19160   [(set (match_operand:DF 0 "register_operand" "=x")
19161         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19162                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19163   "TARGET_SSE2 && TARGET_SSE_MATH"
19164   "maxsd\t{%2, %0|%0, %2}"
19165   [(set_attr "type" "sseadd")
19166    (set_attr "mode" "DF")])
19168 ;; These versions of the min/max patterns implement exactly the operations
19169 ;;   min = (op1 < op2 ? op1 : op2)
19170 ;;   max = (!(op1 < op2) ? op1 : op2)
19171 ;; Their operands are not commutative, and thus they may be used in the
19172 ;; presence of -0.0 and NaN.
19174 (define_insn "*ieee_sminsf3"
19175   [(set (match_operand:SF 0 "register_operand" "=x")
19176         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19177                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19178                    UNSPEC_IEEE_MIN))]
19179   "TARGET_SSE_MATH"
19180   "minss\t{%2, %0|%0, %2}"
19181   [(set_attr "type" "sseadd")
19182    (set_attr "mode" "SF")])
19184 (define_insn "*ieee_smaxsf3"
19185   [(set (match_operand:SF 0 "register_operand" "=x")
19186         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19187                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19188                    UNSPEC_IEEE_MAX))]
19189   "TARGET_SSE_MATH"
19190   "maxss\t{%2, %0|%0, %2}"
19191   [(set_attr "type" "sseadd")
19192    (set_attr "mode" "SF")])
19194 (define_insn "*ieee_smindf3"
19195   [(set (match_operand:DF 0 "register_operand" "=x")
19196         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19197                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19198                    UNSPEC_IEEE_MIN))]
19199   "TARGET_SSE2 && TARGET_SSE_MATH"
19200   "minsd\t{%2, %0|%0, %2}"
19201   [(set_attr "type" "sseadd")
19202    (set_attr "mode" "DF")])
19204 (define_insn "*ieee_smaxdf3"
19205   [(set (match_operand:DF 0 "register_operand" "=x")
19206         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19207                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19208                    UNSPEC_IEEE_MAX))]
19209   "TARGET_SSE2 && TARGET_SSE_MATH"
19210   "maxsd\t{%2, %0|%0, %2}"
19211   [(set_attr "type" "sseadd")
19212    (set_attr "mode" "DF")])
19214 ;; Make two stack loads independent:
19215 ;;   fld aa              fld aa
19216 ;;   fld %st(0)     ->   fld bb
19217 ;;   fmul bb             fmul %st(1), %st
19219 ;; Actually we only match the last two instructions for simplicity.
19220 (define_peephole2
19221   [(set (match_operand 0 "fp_register_operand" "")
19222         (match_operand 1 "fp_register_operand" ""))
19223    (set (match_dup 0)
19224         (match_operator 2 "binary_fp_operator"
19225            [(match_dup 0)
19226             (match_operand 3 "memory_operand" "")]))]
19227   "REGNO (operands[0]) != REGNO (operands[1])"
19228   [(set (match_dup 0) (match_dup 3))
19229    (set (match_dup 0) (match_dup 4))]
19231   ;; The % modifier is not operational anymore in peephole2's, so we have to
19232   ;; swap the operands manually in the case of addition and multiplication.
19233   "if (COMMUTATIVE_ARITH_P (operands[2]))
19234      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19235                                  operands[0], operands[1]);
19236    else
19237      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19238                                  operands[1], operands[0]);")
19240 ;; Conditional addition patterns
19241 (define_expand "addqicc"
19242   [(match_operand:QI 0 "register_operand" "")
19243    (match_operand 1 "comparison_operator" "")
19244    (match_operand:QI 2 "register_operand" "")
19245    (match_operand:QI 3 "const_int_operand" "")]
19246   ""
19247   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19249 (define_expand "addhicc"
19250   [(match_operand:HI 0 "register_operand" "")
19251    (match_operand 1 "comparison_operator" "")
19252    (match_operand:HI 2 "register_operand" "")
19253    (match_operand:HI 3 "const_int_operand" "")]
19254   ""
19255   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19257 (define_expand "addsicc"
19258   [(match_operand:SI 0 "register_operand" "")
19259    (match_operand 1 "comparison_operator" "")
19260    (match_operand:SI 2 "register_operand" "")
19261    (match_operand:SI 3 "const_int_operand" "")]
19262   ""
19263   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19265 (define_expand "adddicc"
19266   [(match_operand:DI 0 "register_operand" "")
19267    (match_operand 1 "comparison_operator" "")
19268    (match_operand:DI 2 "register_operand" "")
19269    (match_operand:DI 3 "const_int_operand" "")]
19270   "TARGET_64BIT"
19271   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19274 ;; Misc patterns (?)
19276 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19277 ;; Otherwise there will be nothing to keep
19278 ;; 
19279 ;; [(set (reg ebp) (reg esp))]
19280 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19281 ;;  (clobber (eflags)]
19282 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19284 ;; in proper program order.
19285 (define_insn "pro_epilogue_adjust_stack_1"
19286   [(set (match_operand:SI 0 "register_operand" "=r,r")
19287         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19288                  (match_operand:SI 2 "immediate_operand" "i,i")))
19289    (clobber (reg:CC FLAGS_REG))
19290    (clobber (mem:BLK (scratch)))]
19291   "!TARGET_64BIT"
19293   switch (get_attr_type (insn))
19294     {
19295     case TYPE_IMOV:
19296       return "mov{l}\t{%1, %0|%0, %1}";
19298     case TYPE_ALU:
19299       if (GET_CODE (operands[2]) == CONST_INT
19300           && (INTVAL (operands[2]) == 128
19301               || (INTVAL (operands[2]) < 0
19302                   && INTVAL (operands[2]) != -128)))
19303         {
19304           operands[2] = GEN_INT (-INTVAL (operands[2]));
19305           return "sub{l}\t{%2, %0|%0, %2}";
19306         }
19307       return "add{l}\t{%2, %0|%0, %2}";
19309     case TYPE_LEA:
19310       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19311       return "lea{l}\t{%a2, %0|%0, %a2}";
19313     default:
19314       gcc_unreachable ();
19315     }
19317   [(set (attr "type")
19318         (cond [(eq_attr "alternative" "0")
19319                  (const_string "alu")
19320                (match_operand:SI 2 "const0_operand" "")
19321                  (const_string "imov")
19322               ]
19323               (const_string "lea")))
19324    (set_attr "mode" "SI")])
19326 (define_insn "pro_epilogue_adjust_stack_rex64"
19327   [(set (match_operand:DI 0 "register_operand" "=r,r")
19328         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19329                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19330    (clobber (reg:CC FLAGS_REG))
19331    (clobber (mem:BLK (scratch)))]
19332   "TARGET_64BIT"
19334   switch (get_attr_type (insn))
19335     {
19336     case TYPE_IMOV:
19337       return "mov{q}\t{%1, %0|%0, %1}";
19339     case TYPE_ALU:
19340       if (GET_CODE (operands[2]) == CONST_INT
19341           /* Avoid overflows.  */
19342           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19343           && (INTVAL (operands[2]) == 128
19344               || (INTVAL (operands[2]) < 0
19345                   && INTVAL (operands[2]) != -128)))
19346         {
19347           operands[2] = GEN_INT (-INTVAL (operands[2]));
19348           return "sub{q}\t{%2, %0|%0, %2}";
19349         }
19350       return "add{q}\t{%2, %0|%0, %2}";
19352     case TYPE_LEA:
19353       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19354       return "lea{q}\t{%a2, %0|%0, %a2}";
19356     default:
19357       gcc_unreachable ();
19358     }
19360   [(set (attr "type")
19361         (cond [(eq_attr "alternative" "0")
19362                  (const_string "alu")
19363                (match_operand:DI 2 "const0_operand" "")
19364                  (const_string "imov")
19365               ]
19366               (const_string "lea")))
19367    (set_attr "mode" "DI")])
19369 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19370   [(set (match_operand:DI 0 "register_operand" "=r,r")
19371         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19372                  (match_operand:DI 3 "immediate_operand" "i,i")))
19373    (use (match_operand:DI 2 "register_operand" "r,r"))
19374    (clobber (reg:CC FLAGS_REG))
19375    (clobber (mem:BLK (scratch)))]
19376   "TARGET_64BIT"
19378   switch (get_attr_type (insn))
19379     {
19380     case TYPE_ALU:
19381       return "add{q}\t{%2, %0|%0, %2}";
19383     case TYPE_LEA:
19384       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19385       return "lea{q}\t{%a2, %0|%0, %a2}";
19387     default:
19388       gcc_unreachable ();
19389     }
19391   [(set_attr "type" "alu,lea")
19392    (set_attr "mode" "DI")])
19394 (define_expand "allocate_stack_worker"
19395   [(match_operand:SI 0 "register_operand" "")]
19396   "TARGET_STACK_PROBE"
19398   if (reload_completed)
19399     {
19400       if (TARGET_64BIT)
19401         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19402       else
19403         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19404     }
19405   else
19406     {
19407       if (TARGET_64BIT)
19408         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19409       else
19410         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19411     }
19412   DONE;
19415 (define_insn "allocate_stack_worker_1"
19416   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19417     UNSPECV_STACK_PROBE)
19418    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19419    (clobber (match_scratch:SI 1 "=0"))
19420    (clobber (reg:CC FLAGS_REG))]
19421   "!TARGET_64BIT && TARGET_STACK_PROBE"
19422   "call\t__alloca"
19423   [(set_attr "type" "multi")
19424    (set_attr "length" "5")])
19426 (define_expand "allocate_stack_worker_postreload"
19427   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19428                                     UNSPECV_STACK_PROBE)
19429               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19430               (clobber (match_dup 0))
19431               (clobber (reg:CC FLAGS_REG))])]
19432   ""
19433   "")
19435 (define_insn "allocate_stack_worker_rex64"
19436   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19437     UNSPECV_STACK_PROBE)
19438    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19439    (clobber (match_scratch:DI 1 "=0"))
19440    (clobber (reg:CC FLAGS_REG))]
19441   "TARGET_64BIT && TARGET_STACK_PROBE"
19442   "call\t__alloca"
19443   [(set_attr "type" "multi")
19444    (set_attr "length" "5")])
19446 (define_expand "allocate_stack_worker_rex64_postreload"
19447   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19448                                     UNSPECV_STACK_PROBE)
19449               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19450               (clobber (match_dup 0))
19451               (clobber (reg:CC FLAGS_REG))])]
19452   ""
19453   "")
19455 (define_expand "allocate_stack"
19456   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19457                    (minus:SI (reg:SI SP_REG)
19458                              (match_operand:SI 1 "general_operand" "")))
19459               (clobber (reg:CC FLAGS_REG))])
19460    (parallel [(set (reg:SI SP_REG)
19461                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19462               (clobber (reg:CC FLAGS_REG))])]
19463   "TARGET_STACK_PROBE"
19465 #ifdef CHECK_STACK_LIMIT
19466   if (GET_CODE (operands[1]) == CONST_INT
19467       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19468     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19469                            operands[1]));
19470   else 
19471 #endif
19472     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19473                                                             operands[1])));
19475   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19476   DONE;
19479 (define_expand "builtin_setjmp_receiver"
19480   [(label_ref (match_operand 0 "" ""))]
19481   "!TARGET_64BIT && flag_pic"
19483   if (TARGET_MACHO)
19484     {
19485       rtx xops[3];
19486       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19487       rtx label_rtx = gen_label_rtx ();
19488       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19489       xops[0] = xops[1] = picreg;
19490       xops[2] = gen_rtx_CONST (SImode,
19491                   gen_rtx_MINUS (SImode,
19492                     gen_rtx_LABEL_REF (SImode, label_rtx),
19493                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19494       ix86_expand_binary_operator (MINUS, SImode, xops);
19495     }
19496   else
19497     emit_insn (gen_set_got (pic_offset_table_rtx));
19498   DONE;
19501 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19503 (define_split
19504   [(set (match_operand 0 "register_operand" "")
19505         (match_operator 3 "promotable_binary_operator"
19506            [(match_operand 1 "register_operand" "")
19507             (match_operand 2 "aligned_operand" "")]))
19508    (clobber (reg:CC FLAGS_REG))]
19509   "! TARGET_PARTIAL_REG_STALL && reload_completed
19510    && ((GET_MODE (operands[0]) == HImode 
19511         && ((!optimize_size && !TARGET_FAST_PREFIX)
19512             /* ??? next two lines just !satisfies_constraint_K (...) */
19513             || GET_CODE (operands[2]) != CONST_INT
19514             || satisfies_constraint_K (operands[2])))
19515        || (GET_MODE (operands[0]) == QImode 
19516            && (TARGET_PROMOTE_QImode || optimize_size)))"
19517   [(parallel [(set (match_dup 0)
19518                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19519               (clobber (reg:CC FLAGS_REG))])]
19520   "operands[0] = gen_lowpart (SImode, operands[0]);
19521    operands[1] = gen_lowpart (SImode, operands[1]);
19522    if (GET_CODE (operands[3]) != ASHIFT)
19523      operands[2] = gen_lowpart (SImode, operands[2]);
19524    PUT_MODE (operands[3], SImode);")
19526 ; Promote the QImode tests, as i386 has encoding of the AND
19527 ; instruction with 32-bit sign-extended immediate and thus the
19528 ; instruction size is unchanged, except in the %eax case for
19529 ; which it is increased by one byte, hence the ! optimize_size.
19530 (define_split
19531   [(set (match_operand 0 "flags_reg_operand" "")
19532         (match_operator 2 "compare_operator"
19533           [(and (match_operand 3 "aligned_operand" "")
19534                 (match_operand 4 "const_int_operand" ""))
19535            (const_int 0)]))
19536    (set (match_operand 1 "register_operand" "")
19537         (and (match_dup 3) (match_dup 4)))]
19538   "! TARGET_PARTIAL_REG_STALL && reload_completed
19539    /* Ensure that the operand will remain sign-extended immediate.  */
19540    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19541    && ! optimize_size
19542    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19543        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19544   [(parallel [(set (match_dup 0)
19545                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19546                                     (const_int 0)]))
19547               (set (match_dup 1)
19548                    (and:SI (match_dup 3) (match_dup 4)))])]
19550   operands[4]
19551     = gen_int_mode (INTVAL (operands[4])
19552                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19553   operands[1] = gen_lowpart (SImode, operands[1]);
19554   operands[3] = gen_lowpart (SImode, operands[3]);
19557 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19558 ; the TEST instruction with 32-bit sign-extended immediate and thus
19559 ; the instruction size would at least double, which is not what we
19560 ; want even with ! optimize_size.
19561 (define_split
19562   [(set (match_operand 0 "flags_reg_operand" "")
19563         (match_operator 1 "compare_operator"
19564           [(and (match_operand:HI 2 "aligned_operand" "")
19565                 (match_operand:HI 3 "const_int_operand" ""))
19566            (const_int 0)]))]
19567   "! TARGET_PARTIAL_REG_STALL && reload_completed
19568    /* Ensure that the operand will remain sign-extended immediate.  */
19569    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19570    && ! TARGET_FAST_PREFIX
19571    && ! optimize_size"
19572   [(set (match_dup 0)
19573         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19574                          (const_int 0)]))]
19576   operands[3]
19577     = gen_int_mode (INTVAL (operands[3])
19578                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19579   operands[2] = gen_lowpart (SImode, operands[2]);
19582 (define_split
19583   [(set (match_operand 0 "register_operand" "")
19584         (neg (match_operand 1 "register_operand" "")))
19585    (clobber (reg:CC FLAGS_REG))]
19586   "! TARGET_PARTIAL_REG_STALL && reload_completed
19587    && (GET_MODE (operands[0]) == HImode
19588        || (GET_MODE (operands[0]) == QImode 
19589            && (TARGET_PROMOTE_QImode || optimize_size)))"
19590   [(parallel [(set (match_dup 0)
19591                    (neg:SI (match_dup 1)))
19592               (clobber (reg:CC FLAGS_REG))])]
19593   "operands[0] = gen_lowpart (SImode, operands[0]);
19594    operands[1] = gen_lowpart (SImode, operands[1]);")
19596 (define_split
19597   [(set (match_operand 0 "register_operand" "")
19598         (not (match_operand 1 "register_operand" "")))]
19599   "! TARGET_PARTIAL_REG_STALL && reload_completed
19600    && (GET_MODE (operands[0]) == HImode
19601        || (GET_MODE (operands[0]) == QImode 
19602            && (TARGET_PROMOTE_QImode || optimize_size)))"
19603   [(set (match_dup 0)
19604         (not:SI (match_dup 1)))]
19605   "operands[0] = gen_lowpart (SImode, operands[0]);
19606    operands[1] = gen_lowpart (SImode, operands[1]);")
19608 (define_split 
19609   [(set (match_operand 0 "register_operand" "")
19610         (if_then_else (match_operator 1 "comparison_operator" 
19611                                 [(reg FLAGS_REG) (const_int 0)])
19612                       (match_operand 2 "register_operand" "")
19613                       (match_operand 3 "register_operand" "")))]
19614   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19615    && (GET_MODE (operands[0]) == HImode
19616        || (GET_MODE (operands[0]) == QImode 
19617            && (TARGET_PROMOTE_QImode || optimize_size)))"
19618   [(set (match_dup 0)
19619         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19620   "operands[0] = gen_lowpart (SImode, operands[0]);
19621    operands[2] = gen_lowpart (SImode, operands[2]);
19622    operands[3] = gen_lowpart (SImode, operands[3]);")
19623                         
19625 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19626 ;; transform a complex memory operation into two memory to register operations.
19628 ;; Don't push memory operands
19629 (define_peephole2
19630   [(set (match_operand:SI 0 "push_operand" "")
19631         (match_operand:SI 1 "memory_operand" ""))
19632    (match_scratch:SI 2 "r")]
19633   "!optimize_size && !TARGET_PUSH_MEMORY
19634    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19635   [(set (match_dup 2) (match_dup 1))
19636    (set (match_dup 0) (match_dup 2))]
19637   "")
19639 (define_peephole2
19640   [(set (match_operand:DI 0 "push_operand" "")
19641         (match_operand:DI 1 "memory_operand" ""))
19642    (match_scratch:DI 2 "r")]
19643   "!optimize_size && !TARGET_PUSH_MEMORY
19644    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19645   [(set (match_dup 2) (match_dup 1))
19646    (set (match_dup 0) (match_dup 2))]
19647   "")
19649 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19650 ;; SImode pushes.
19651 (define_peephole2
19652   [(set (match_operand:SF 0 "push_operand" "")
19653         (match_operand:SF 1 "memory_operand" ""))
19654    (match_scratch:SF 2 "r")]
19655   "!optimize_size && !TARGET_PUSH_MEMORY
19656    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19657   [(set (match_dup 2) (match_dup 1))
19658    (set (match_dup 0) (match_dup 2))]
19659   "")
19661 (define_peephole2
19662   [(set (match_operand:HI 0 "push_operand" "")
19663         (match_operand:HI 1 "memory_operand" ""))
19664    (match_scratch:HI 2 "r")]
19665   "!optimize_size && !TARGET_PUSH_MEMORY
19666    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19667   [(set (match_dup 2) (match_dup 1))
19668    (set (match_dup 0) (match_dup 2))]
19669   "")
19671 (define_peephole2
19672   [(set (match_operand:QI 0 "push_operand" "")
19673         (match_operand:QI 1 "memory_operand" ""))
19674    (match_scratch:QI 2 "q")]
19675   "!optimize_size && !TARGET_PUSH_MEMORY
19676    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19677   [(set (match_dup 2) (match_dup 1))
19678    (set (match_dup 0) (match_dup 2))]
19679   "")
19681 ;; Don't move an immediate directly to memory when the instruction
19682 ;; gets too big.
19683 (define_peephole2
19684   [(match_scratch:SI 1 "r")
19685    (set (match_operand:SI 0 "memory_operand" "")
19686         (const_int 0))]
19687   "! optimize_size
19688    && ! TARGET_USE_MOV0
19689    && TARGET_SPLIT_LONG_MOVES
19690    && get_attr_length (insn) >= ix86_cost->large_insn
19691    && peep2_regno_dead_p (0, FLAGS_REG)"
19692   [(parallel [(set (match_dup 1) (const_int 0))
19693               (clobber (reg:CC FLAGS_REG))])
19694    (set (match_dup 0) (match_dup 1))]
19695   "")
19697 (define_peephole2
19698   [(match_scratch:HI 1 "r")
19699    (set (match_operand:HI 0 "memory_operand" "")
19700         (const_int 0))]
19701   "! optimize_size
19702    && ! TARGET_USE_MOV0
19703    && TARGET_SPLIT_LONG_MOVES
19704    && get_attr_length (insn) >= ix86_cost->large_insn
19705    && peep2_regno_dead_p (0, FLAGS_REG)"
19706   [(parallel [(set (match_dup 2) (const_int 0))
19707               (clobber (reg:CC FLAGS_REG))])
19708    (set (match_dup 0) (match_dup 1))]
19709   "operands[2] = gen_lowpart (SImode, operands[1]);")
19711 (define_peephole2
19712   [(match_scratch:QI 1 "q")
19713    (set (match_operand:QI 0 "memory_operand" "")
19714         (const_int 0))]
19715   "! optimize_size
19716    && ! TARGET_USE_MOV0
19717    && TARGET_SPLIT_LONG_MOVES
19718    && get_attr_length (insn) >= ix86_cost->large_insn
19719    && peep2_regno_dead_p (0, FLAGS_REG)"
19720   [(parallel [(set (match_dup 2) (const_int 0))
19721               (clobber (reg:CC FLAGS_REG))])
19722    (set (match_dup 0) (match_dup 1))]
19723   "operands[2] = gen_lowpart (SImode, operands[1]);")
19725 (define_peephole2
19726   [(match_scratch:SI 2 "r")
19727    (set (match_operand:SI 0 "memory_operand" "")
19728         (match_operand:SI 1 "immediate_operand" ""))]
19729   "! optimize_size
19730    && get_attr_length (insn) >= ix86_cost->large_insn
19731    && TARGET_SPLIT_LONG_MOVES"
19732   [(set (match_dup 2) (match_dup 1))
19733    (set (match_dup 0) (match_dup 2))]
19734   "")
19736 (define_peephole2
19737   [(match_scratch:HI 2 "r")
19738    (set (match_operand:HI 0 "memory_operand" "")
19739         (match_operand:HI 1 "immediate_operand" ""))]
19740   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19741   && TARGET_SPLIT_LONG_MOVES"
19742   [(set (match_dup 2) (match_dup 1))
19743    (set (match_dup 0) (match_dup 2))]
19744   "")
19746 (define_peephole2
19747   [(match_scratch:QI 2 "q")
19748    (set (match_operand:QI 0 "memory_operand" "")
19749         (match_operand:QI 1 "immediate_operand" ""))]
19750   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19751   && TARGET_SPLIT_LONG_MOVES"
19752   [(set (match_dup 2) (match_dup 1))
19753    (set (match_dup 0) (match_dup 2))]
19754   "")
19756 ;; Don't compare memory with zero, load and use a test instead.
19757 (define_peephole2
19758   [(set (match_operand 0 "flags_reg_operand" "")
19759         (match_operator 1 "compare_operator"
19760           [(match_operand:SI 2 "memory_operand" "")
19761            (const_int 0)]))
19762    (match_scratch:SI 3 "r")]
19763   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19764   [(set (match_dup 3) (match_dup 2))
19765    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19766   "")
19768 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19769 ;; Don't split NOTs with a displacement operand, because resulting XOR
19770 ;; will not be pairable anyway.
19772 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19773 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19774 ;; so this split helps here as well.
19776 ;; Note: Can't do this as a regular split because we can't get proper
19777 ;; lifetime information then.
19779 (define_peephole2
19780   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19781         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19782   "!optimize_size
19783    && peep2_regno_dead_p (0, FLAGS_REG)
19784    && ((TARGET_PENTIUM 
19785         && (GET_CODE (operands[0]) != MEM
19786             || !memory_displacement_operand (operands[0], SImode)))
19787        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19788   [(parallel [(set (match_dup 0)
19789                    (xor:SI (match_dup 1) (const_int -1)))
19790               (clobber (reg:CC FLAGS_REG))])]
19791   "")
19793 (define_peephole2
19794   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19795         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19796   "!optimize_size
19797    && peep2_regno_dead_p (0, FLAGS_REG)
19798    && ((TARGET_PENTIUM 
19799         && (GET_CODE (operands[0]) != MEM
19800             || !memory_displacement_operand (operands[0], HImode)))
19801        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19802   [(parallel [(set (match_dup 0)
19803                    (xor:HI (match_dup 1) (const_int -1)))
19804               (clobber (reg:CC FLAGS_REG))])]
19805   "")
19807 (define_peephole2
19808   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19809         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19810   "!optimize_size
19811    && peep2_regno_dead_p (0, FLAGS_REG)
19812    && ((TARGET_PENTIUM 
19813         && (GET_CODE (operands[0]) != MEM
19814             || !memory_displacement_operand (operands[0], QImode)))
19815        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19816   [(parallel [(set (match_dup 0)
19817                    (xor:QI (match_dup 1) (const_int -1)))
19818               (clobber (reg:CC FLAGS_REG))])]
19819   "")
19821 ;; Non pairable "test imm, reg" instructions can be translated to
19822 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19823 ;; byte opcode instead of two, have a short form for byte operands),
19824 ;; so do it for other CPUs as well.  Given that the value was dead,
19825 ;; this should not create any new dependencies.  Pass on the sub-word
19826 ;; versions if we're concerned about partial register stalls.
19828 (define_peephole2
19829   [(set (match_operand 0 "flags_reg_operand" "")
19830         (match_operator 1 "compare_operator"
19831           [(and:SI (match_operand:SI 2 "register_operand" "")
19832                    (match_operand:SI 3 "immediate_operand" ""))
19833            (const_int 0)]))]
19834   "ix86_match_ccmode (insn, CCNOmode)
19835    && (true_regnum (operands[2]) != 0
19836        || satisfies_constraint_K (operands[3]))
19837    && peep2_reg_dead_p (1, operands[2])"
19838   [(parallel
19839      [(set (match_dup 0)
19840            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19841                             (const_int 0)]))
19842       (set (match_dup 2)
19843            (and:SI (match_dup 2) (match_dup 3)))])]
19844   "")
19846 ;; We don't need to handle HImode case, because it will be promoted to SImode
19847 ;; on ! TARGET_PARTIAL_REG_STALL
19849 (define_peephole2
19850   [(set (match_operand 0 "flags_reg_operand" "")
19851         (match_operator 1 "compare_operator"
19852           [(and:QI (match_operand:QI 2 "register_operand" "")
19853                    (match_operand:QI 3 "immediate_operand" ""))
19854            (const_int 0)]))]
19855   "! TARGET_PARTIAL_REG_STALL
19856    && ix86_match_ccmode (insn, CCNOmode)
19857    && true_regnum (operands[2]) != 0
19858    && peep2_reg_dead_p (1, operands[2])"
19859   [(parallel
19860      [(set (match_dup 0)
19861            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19862                             (const_int 0)]))
19863       (set (match_dup 2)
19864            (and:QI (match_dup 2) (match_dup 3)))])]
19865   "")
19867 (define_peephole2
19868   [(set (match_operand 0 "flags_reg_operand" "")
19869         (match_operator 1 "compare_operator"
19870           [(and:SI
19871              (zero_extract:SI
19872                (match_operand 2 "ext_register_operand" "")
19873                (const_int 8)
19874                (const_int 8))
19875              (match_operand 3 "const_int_operand" ""))
19876            (const_int 0)]))]
19877   "! TARGET_PARTIAL_REG_STALL
19878    && ix86_match_ccmode (insn, CCNOmode)
19879    && true_regnum (operands[2]) != 0
19880    && peep2_reg_dead_p (1, operands[2])"
19881   [(parallel [(set (match_dup 0)
19882                    (match_op_dup 1
19883                      [(and:SI
19884                         (zero_extract:SI
19885                           (match_dup 2)
19886                           (const_int 8)
19887                           (const_int 8))
19888                         (match_dup 3))
19889                       (const_int 0)]))
19890               (set (zero_extract:SI (match_dup 2)
19891                                     (const_int 8)
19892                                     (const_int 8))
19893                    (and:SI 
19894                      (zero_extract:SI
19895                        (match_dup 2)
19896                        (const_int 8)
19897                        (const_int 8))
19898                      (match_dup 3)))])]
19899   "")
19901 ;; Don't do logical operations with memory inputs.
19902 (define_peephole2
19903   [(match_scratch:SI 2 "r")
19904    (parallel [(set (match_operand:SI 0 "register_operand" "")
19905                    (match_operator:SI 3 "arith_or_logical_operator"
19906                      [(match_dup 0)
19907                       (match_operand:SI 1 "memory_operand" "")]))
19908               (clobber (reg:CC FLAGS_REG))])]
19909   "! optimize_size && ! TARGET_READ_MODIFY"
19910   [(set (match_dup 2) (match_dup 1))
19911    (parallel [(set (match_dup 0)
19912                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19913               (clobber (reg:CC FLAGS_REG))])]
19914   "")
19916 (define_peephole2
19917   [(match_scratch:SI 2 "r")
19918    (parallel [(set (match_operand:SI 0 "register_operand" "")
19919                    (match_operator:SI 3 "arith_or_logical_operator"
19920                      [(match_operand:SI 1 "memory_operand" "")
19921                       (match_dup 0)]))
19922               (clobber (reg:CC FLAGS_REG))])]
19923   "! optimize_size && ! TARGET_READ_MODIFY"
19924   [(set (match_dup 2) (match_dup 1))
19925    (parallel [(set (match_dup 0)
19926                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19927               (clobber (reg:CC FLAGS_REG))])]
19928   "")
19930 ; Don't do logical operations with memory outputs
19932 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19933 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19934 ; the same decoder scheduling characteristics as the original.
19936 (define_peephole2
19937   [(match_scratch:SI 2 "r")
19938    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19939                    (match_operator:SI 3 "arith_or_logical_operator"
19940                      [(match_dup 0)
19941                       (match_operand:SI 1 "nonmemory_operand" "")]))
19942               (clobber (reg:CC FLAGS_REG))])]
19943   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19944   [(set (match_dup 2) (match_dup 0))
19945    (parallel [(set (match_dup 2)
19946                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19947               (clobber (reg:CC FLAGS_REG))])
19948    (set (match_dup 0) (match_dup 2))]
19949   "")
19951 (define_peephole2
19952   [(match_scratch:SI 2 "r")
19953    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19954                    (match_operator:SI 3 "arith_or_logical_operator"
19955                      [(match_operand:SI 1 "nonmemory_operand" "")
19956                       (match_dup 0)]))
19957               (clobber (reg:CC FLAGS_REG))])]
19958   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19959   [(set (match_dup 2) (match_dup 0))
19960    (parallel [(set (match_dup 2)
19961                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19962               (clobber (reg:CC FLAGS_REG))])
19963    (set (match_dup 0) (match_dup 2))]
19964   "")
19966 ;; Attempt to always use XOR for zeroing registers.
19967 (define_peephole2
19968   [(set (match_operand 0 "register_operand" "")
19969         (match_operand 1 "const0_operand" ""))]
19970   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19971    && (! TARGET_USE_MOV0 || optimize_size)
19972    && GENERAL_REG_P (operands[0])
19973    && peep2_regno_dead_p (0, FLAGS_REG)"
19974   [(parallel [(set (match_dup 0) (const_int 0))
19975               (clobber (reg:CC FLAGS_REG))])]
19977   operands[0] = gen_lowpart (word_mode, operands[0]);
19980 (define_peephole2
19981   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19982         (const_int 0))]
19983   "(GET_MODE (operands[0]) == QImode
19984     || GET_MODE (operands[0]) == HImode)
19985    && (! TARGET_USE_MOV0 || optimize_size)
19986    && peep2_regno_dead_p (0, FLAGS_REG)"
19987   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19988               (clobber (reg:CC FLAGS_REG))])])
19990 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19991 (define_peephole2
19992   [(set (match_operand 0 "register_operand" "")
19993         (const_int -1))]
19994   "(GET_MODE (operands[0]) == HImode
19995     || GET_MODE (operands[0]) == SImode 
19996     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19997    && (optimize_size || TARGET_PENTIUM)
19998    && peep2_regno_dead_p (0, FLAGS_REG)"
19999   [(parallel [(set (match_dup 0) (const_int -1))
20000               (clobber (reg:CC FLAGS_REG))])]
20001   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20002                               operands[0]);")
20004 ;; Attempt to convert simple leas to adds. These can be created by
20005 ;; move expanders.
20006 (define_peephole2
20007   [(set (match_operand:SI 0 "register_operand" "")
20008         (plus:SI (match_dup 0)
20009                  (match_operand:SI 1 "nonmemory_operand" "")))]
20010   "peep2_regno_dead_p (0, FLAGS_REG)"
20011   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20012               (clobber (reg:CC FLAGS_REG))])]
20013   "")
20015 (define_peephole2
20016   [(set (match_operand:SI 0 "register_operand" "")
20017         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20018                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20019   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20020   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20021               (clobber (reg:CC FLAGS_REG))])]
20022   "operands[2] = gen_lowpart (SImode, operands[2]);")
20024 (define_peephole2
20025   [(set (match_operand:DI 0 "register_operand" "")
20026         (plus:DI (match_dup 0)
20027                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20028   "peep2_regno_dead_p (0, FLAGS_REG)"
20029   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20030               (clobber (reg:CC FLAGS_REG))])]
20031   "")
20033 (define_peephole2
20034   [(set (match_operand:SI 0 "register_operand" "")
20035         (mult:SI (match_dup 0)
20036                  (match_operand:SI 1 "const_int_operand" "")))]
20037   "exact_log2 (INTVAL (operands[1])) >= 0
20038    && peep2_regno_dead_p (0, FLAGS_REG)"
20039   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20040               (clobber (reg:CC FLAGS_REG))])]
20041   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20043 (define_peephole2
20044   [(set (match_operand:DI 0 "register_operand" "")
20045         (mult:DI (match_dup 0)
20046                  (match_operand:DI 1 "const_int_operand" "")))]
20047   "exact_log2 (INTVAL (operands[1])) >= 0
20048    && peep2_regno_dead_p (0, FLAGS_REG)"
20049   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20050               (clobber (reg:CC FLAGS_REG))])]
20051   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20053 (define_peephole2
20054   [(set (match_operand:SI 0 "register_operand" "")
20055         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20056                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20057   "exact_log2 (INTVAL (operands[2])) >= 0
20058    && REGNO (operands[0]) == REGNO (operands[1])
20059    && peep2_regno_dead_p (0, FLAGS_REG)"
20060   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20061               (clobber (reg:CC FLAGS_REG))])]
20062   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20064 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20065 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20066 ;; many CPUs it is also faster, since special hardware to avoid esp
20067 ;; dependencies is present.
20069 ;; While some of these conversions may be done using splitters, we use peepholes
20070 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20072 ;; Convert prologue esp subtractions to push.
20073 ;; We need register to push.  In order to keep verify_flow_info happy we have
20074 ;; two choices
20075 ;; - use scratch and clobber it in order to avoid dependencies
20076 ;; - use already live register
20077 ;; We can't use the second way right now, since there is no reliable way how to
20078 ;; verify that given register is live.  First choice will also most likely in
20079 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20080 ;; call clobbered registers are dead.  We may want to use base pointer as an
20081 ;; alternative when no register is available later.
20083 (define_peephole2
20084   [(match_scratch:SI 0 "r")
20085    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20086               (clobber (reg:CC FLAGS_REG))
20087               (clobber (mem:BLK (scratch)))])]
20088   "optimize_size || !TARGET_SUB_ESP_4"
20089   [(clobber (match_dup 0))
20090    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20091               (clobber (mem:BLK (scratch)))])])
20093 (define_peephole2
20094   [(match_scratch:SI 0 "r")
20095    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20096               (clobber (reg:CC FLAGS_REG))
20097               (clobber (mem:BLK (scratch)))])]
20098   "optimize_size || !TARGET_SUB_ESP_8"
20099   [(clobber (match_dup 0))
20100    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20101    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20102               (clobber (mem:BLK (scratch)))])])
20104 ;; Convert esp subtractions to push.
20105 (define_peephole2
20106   [(match_scratch:SI 0 "r")
20107    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20108               (clobber (reg:CC FLAGS_REG))])]
20109   "optimize_size || !TARGET_SUB_ESP_4"
20110   [(clobber (match_dup 0))
20111    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20113 (define_peephole2
20114   [(match_scratch:SI 0 "r")
20115    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20116               (clobber (reg:CC FLAGS_REG))])]
20117   "optimize_size || !TARGET_SUB_ESP_8"
20118   [(clobber (match_dup 0))
20119    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20120    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20122 ;; Convert epilogue deallocator to pop.
20123 (define_peephole2
20124   [(match_scratch:SI 0 "r")
20125    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20126               (clobber (reg:CC FLAGS_REG))
20127               (clobber (mem:BLK (scratch)))])]
20128   "optimize_size || !TARGET_ADD_ESP_4"
20129   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20130               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20131               (clobber (mem:BLK (scratch)))])]
20132   "")
20134 ;; Two pops case is tricky, since pop causes dependency on destination register.
20135 ;; We use two registers if available.
20136 (define_peephole2
20137   [(match_scratch:SI 0 "r")
20138    (match_scratch:SI 1 "r")
20139    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20140               (clobber (reg:CC FLAGS_REG))
20141               (clobber (mem:BLK (scratch)))])]
20142   "optimize_size || !TARGET_ADD_ESP_8"
20143   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20144               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20145               (clobber (mem:BLK (scratch)))])
20146    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20147               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20148   "")
20150 (define_peephole2
20151   [(match_scratch:SI 0 "r")
20152    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20153               (clobber (reg:CC FLAGS_REG))
20154               (clobber (mem:BLK (scratch)))])]
20155   "optimize_size"
20156   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20157               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20158               (clobber (mem:BLK (scratch)))])
20159    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20160               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20161   "")
20163 ;; Convert esp additions to pop.
20164 (define_peephole2
20165   [(match_scratch:SI 0 "r")
20166    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20167               (clobber (reg:CC FLAGS_REG))])]
20168   ""
20169   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20170               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20171   "")
20173 ;; Two pops case is tricky, since pop causes dependency on destination register.
20174 ;; We use two registers if available.
20175 (define_peephole2
20176   [(match_scratch:SI 0 "r")
20177    (match_scratch:SI 1 "r")
20178    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20179               (clobber (reg:CC FLAGS_REG))])]
20180   ""
20181   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20182               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20183    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20184               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20185   "")
20187 (define_peephole2
20188   [(match_scratch:SI 0 "r")
20189    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20190               (clobber (reg:CC FLAGS_REG))])]
20191   "optimize_size"
20192   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20193               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20194    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20195               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20196   "")
20198 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20199 ;; required and register dies.  Similarly for 128 to plus -128.
20200 (define_peephole2
20201   [(set (match_operand 0 "flags_reg_operand" "")
20202         (match_operator 1 "compare_operator"
20203           [(match_operand 2 "register_operand" "")
20204            (match_operand 3 "const_int_operand" "")]))]
20205   "(INTVAL (operands[3]) == -1
20206     || INTVAL (operands[3]) == 1
20207     || INTVAL (operands[3]) == 128)
20208    && ix86_match_ccmode (insn, CCGCmode)
20209    && peep2_reg_dead_p (1, operands[2])"
20210   [(parallel [(set (match_dup 0)
20211                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20212               (clobber (match_dup 2))])]
20213   "")
20215 (define_peephole2
20216   [(match_scratch:DI 0 "r")
20217    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20218               (clobber (reg:CC FLAGS_REG))
20219               (clobber (mem:BLK (scratch)))])]
20220   "optimize_size || !TARGET_SUB_ESP_4"
20221   [(clobber (match_dup 0))
20222    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20223               (clobber (mem:BLK (scratch)))])])
20225 (define_peephole2
20226   [(match_scratch:DI 0 "r")
20227    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20228               (clobber (reg:CC FLAGS_REG))
20229               (clobber (mem:BLK (scratch)))])]
20230   "optimize_size || !TARGET_SUB_ESP_8"
20231   [(clobber (match_dup 0))
20232    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20233    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20234               (clobber (mem:BLK (scratch)))])])
20236 ;; Convert esp subtractions to push.
20237 (define_peephole2
20238   [(match_scratch:DI 0 "r")
20239    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20240               (clobber (reg:CC FLAGS_REG))])]
20241   "optimize_size || !TARGET_SUB_ESP_4"
20242   [(clobber (match_dup 0))
20243    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20245 (define_peephole2
20246   [(match_scratch:DI 0 "r")
20247    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20248               (clobber (reg:CC FLAGS_REG))])]
20249   "optimize_size || !TARGET_SUB_ESP_8"
20250   [(clobber (match_dup 0))
20251    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20252    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20254 ;; Convert epilogue deallocator to pop.
20255 (define_peephole2
20256   [(match_scratch:DI 0 "r")
20257    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20258               (clobber (reg:CC FLAGS_REG))
20259               (clobber (mem:BLK (scratch)))])]
20260   "optimize_size || !TARGET_ADD_ESP_4"
20261   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20262               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20263               (clobber (mem:BLK (scratch)))])]
20264   "")
20266 ;; Two pops case is tricky, since pop causes dependency on destination register.
20267 ;; We use two registers if available.
20268 (define_peephole2
20269   [(match_scratch:DI 0 "r")
20270    (match_scratch:DI 1 "r")
20271    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20272               (clobber (reg:CC FLAGS_REG))
20273               (clobber (mem:BLK (scratch)))])]
20274   "optimize_size || !TARGET_ADD_ESP_8"
20275   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20276               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20277               (clobber (mem:BLK (scratch)))])
20278    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20279               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20280   "")
20282 (define_peephole2
20283   [(match_scratch:DI 0 "r")
20284    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20285               (clobber (reg:CC FLAGS_REG))
20286               (clobber (mem:BLK (scratch)))])]
20287   "optimize_size"
20288   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20289               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20290               (clobber (mem:BLK (scratch)))])
20291    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20292               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20293   "")
20295 ;; Convert esp additions to pop.
20296 (define_peephole2
20297   [(match_scratch:DI 0 "r")
20298    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20299               (clobber (reg:CC FLAGS_REG))])]
20300   ""
20301   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20302               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20303   "")
20305 ;; Two pops case is tricky, since pop causes dependency on destination register.
20306 ;; We use two registers if available.
20307 (define_peephole2
20308   [(match_scratch:DI 0 "r")
20309    (match_scratch:DI 1 "r")
20310    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20311               (clobber (reg:CC FLAGS_REG))])]
20312   ""
20313   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20314               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20315    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20316               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20317   "")
20319 (define_peephole2
20320   [(match_scratch:DI 0 "r")
20321    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20322               (clobber (reg:CC FLAGS_REG))])]
20323   "optimize_size"
20324   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20325               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20326    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20327               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20328   "")
20330 ;; Convert imul by three, five and nine into lea
20331 (define_peephole2
20332   [(parallel
20333     [(set (match_operand:SI 0 "register_operand" "")
20334           (mult:SI (match_operand:SI 1 "register_operand" "")
20335                    (match_operand:SI 2 "const_int_operand" "")))
20336      (clobber (reg:CC FLAGS_REG))])]
20337   "INTVAL (operands[2]) == 3
20338    || INTVAL (operands[2]) == 5
20339    || INTVAL (operands[2]) == 9"
20340   [(set (match_dup 0)
20341         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20342                  (match_dup 1)))]
20343   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20345 (define_peephole2
20346   [(parallel
20347     [(set (match_operand:SI 0 "register_operand" "")
20348           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20349                    (match_operand:SI 2 "const_int_operand" "")))
20350      (clobber (reg:CC FLAGS_REG))])]
20351   "!optimize_size 
20352    && (INTVAL (operands[2]) == 3
20353        || INTVAL (operands[2]) == 5
20354        || INTVAL (operands[2]) == 9)"
20355   [(set (match_dup 0) (match_dup 1))
20356    (set (match_dup 0)
20357         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20358                  (match_dup 0)))]
20359   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20361 (define_peephole2
20362   [(parallel
20363     [(set (match_operand:DI 0 "register_operand" "")
20364           (mult:DI (match_operand:DI 1 "register_operand" "")
20365                    (match_operand:DI 2 "const_int_operand" "")))
20366      (clobber (reg:CC FLAGS_REG))])]
20367   "TARGET_64BIT
20368    && (INTVAL (operands[2]) == 3
20369        || INTVAL (operands[2]) == 5
20370        || INTVAL (operands[2]) == 9)"
20371   [(set (match_dup 0)
20372         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20373                  (match_dup 1)))]
20374   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20376 (define_peephole2
20377   [(parallel
20378     [(set (match_operand:DI 0 "register_operand" "")
20379           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20380                    (match_operand:DI 2 "const_int_operand" "")))
20381      (clobber (reg:CC FLAGS_REG))])]
20382   "TARGET_64BIT
20383    && !optimize_size 
20384    && (INTVAL (operands[2]) == 3
20385        || INTVAL (operands[2]) == 5
20386        || INTVAL (operands[2]) == 9)"
20387   [(set (match_dup 0) (match_dup 1))
20388    (set (match_dup 0)
20389         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20390                  (match_dup 0)))]
20391   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20393 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20394 ;; imul $32bit_imm, reg, reg is direct decoded.
20395 (define_peephole2
20396   [(match_scratch:DI 3 "r")
20397    (parallel [(set (match_operand:DI 0 "register_operand" "")
20398                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20399                             (match_operand:DI 2 "immediate_operand" "")))
20400               (clobber (reg:CC FLAGS_REG))])]
20401   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20402    && !satisfies_constraint_K (operands[2])"
20403   [(set (match_dup 3) (match_dup 1))
20404    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20405               (clobber (reg:CC FLAGS_REG))])]
20408 (define_peephole2
20409   [(match_scratch:SI 3 "r")
20410    (parallel [(set (match_operand:SI 0 "register_operand" "")
20411                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20412                             (match_operand:SI 2 "immediate_operand" "")))
20413               (clobber (reg:CC FLAGS_REG))])]
20414   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20415    && !satisfies_constraint_K (operands[2])"
20416   [(set (match_dup 3) (match_dup 1))
20417    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20418               (clobber (reg:CC FLAGS_REG))])]
20421 (define_peephole2
20422   [(match_scratch:SI 3 "r")
20423    (parallel [(set (match_operand:DI 0 "register_operand" "")
20424                    (zero_extend:DI
20425                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20426                               (match_operand:SI 2 "immediate_operand" ""))))
20427               (clobber (reg:CC FLAGS_REG))])]
20428   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20429    && !satisfies_constraint_K (operands[2])"
20430   [(set (match_dup 3) (match_dup 1))
20431    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20432               (clobber (reg:CC FLAGS_REG))])]
20435 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20436 ;; Convert it into imul reg, reg
20437 ;; It would be better to force assembler to encode instruction using long
20438 ;; immediate, but there is apparently no way to do so.
20439 (define_peephole2
20440   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20441                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20442                             (match_operand:DI 2 "const_int_operand" "")))
20443               (clobber (reg:CC FLAGS_REG))])
20444    (match_scratch:DI 3 "r")]
20445   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20446    && satisfies_constraint_K (operands[2])"
20447   [(set (match_dup 3) (match_dup 2))
20448    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20449               (clobber (reg:CC FLAGS_REG))])]
20451   if (!rtx_equal_p (operands[0], operands[1]))
20452     emit_move_insn (operands[0], operands[1]);
20455 (define_peephole2
20456   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20457                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20458                             (match_operand:SI 2 "const_int_operand" "")))
20459               (clobber (reg:CC FLAGS_REG))])
20460    (match_scratch:SI 3 "r")]
20461   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20462    && satisfies_constraint_K (operands[2])"
20463   [(set (match_dup 3) (match_dup 2))
20464    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20465               (clobber (reg:CC FLAGS_REG))])]
20467   if (!rtx_equal_p (operands[0], operands[1]))
20468     emit_move_insn (operands[0], operands[1]);
20471 (define_peephole2
20472   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20473                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20474                             (match_operand:HI 2 "immediate_operand" "")))
20475               (clobber (reg:CC FLAGS_REG))])
20476    (match_scratch:HI 3 "r")]
20477   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20478   [(set (match_dup 3) (match_dup 2))
20479    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20480               (clobber (reg:CC FLAGS_REG))])]
20482   if (!rtx_equal_p (operands[0], operands[1]))
20483     emit_move_insn (operands[0], operands[1]);
20486 ;; After splitting up read-modify operations, array accesses with memory
20487 ;; operands might end up in form:
20488 ;;  sall    $2, %eax
20489 ;;  movl    4(%esp), %edx
20490 ;;  addl    %edx, %eax
20491 ;; instead of pre-splitting:
20492 ;;  sall    $2, %eax
20493 ;;  addl    4(%esp), %eax
20494 ;; Turn it into:
20495 ;;  movl    4(%esp), %edx
20496 ;;  leal    (%edx,%eax,4), %eax
20498 (define_peephole2
20499   [(parallel [(set (match_operand 0 "register_operand" "")
20500                    (ashift (match_operand 1 "register_operand" "")
20501                            (match_operand 2 "const_int_operand" "")))
20502                (clobber (reg:CC FLAGS_REG))])
20503    (set (match_operand 3 "register_operand")
20504         (match_operand 4 "x86_64_general_operand" ""))
20505    (parallel [(set (match_operand 5 "register_operand" "")
20506                    (plus (match_operand 6 "register_operand" "")
20507                          (match_operand 7 "register_operand" "")))
20508                    (clobber (reg:CC FLAGS_REG))])]
20509   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20510    /* Validate MODE for lea.  */
20511    && ((!TARGET_PARTIAL_REG_STALL
20512         && (GET_MODE (operands[0]) == QImode
20513             || GET_MODE (operands[0]) == HImode))
20514        || GET_MODE (operands[0]) == SImode 
20515        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20516    /* We reorder load and the shift.  */
20517    && !rtx_equal_p (operands[1], operands[3])
20518    && !reg_overlap_mentioned_p (operands[0], operands[4])
20519    /* Last PLUS must consist of operand 0 and 3.  */
20520    && !rtx_equal_p (operands[0], operands[3])
20521    && (rtx_equal_p (operands[3], operands[6])
20522        || rtx_equal_p (operands[3], operands[7]))
20523    && (rtx_equal_p (operands[0], operands[6])
20524        || rtx_equal_p (operands[0], operands[7]))
20525    /* The intermediate operand 0 must die or be same as output.  */
20526    && (rtx_equal_p (operands[0], operands[5])
20527        || peep2_reg_dead_p (3, operands[0]))"
20528   [(set (match_dup 3) (match_dup 4))
20529    (set (match_dup 0) (match_dup 1))]
20531   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20532   int scale = 1 << INTVAL (operands[2]);
20533   rtx index = gen_lowpart (Pmode, operands[1]);
20534   rtx base = gen_lowpart (Pmode, operands[3]);
20535   rtx dest = gen_lowpart (mode, operands[5]);
20537   operands[1] = gen_rtx_PLUS (Pmode, base,
20538                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20539   if (mode != Pmode)
20540     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20541   operands[0] = dest;
20544 ;; Call-value patterns last so that the wildcard operand does not
20545 ;; disrupt insn-recog's switch tables.
20547 (define_insn "*call_value_pop_0"
20548   [(set (match_operand 0 "" "")
20549         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20550               (match_operand:SI 2 "" "")))
20551    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20552                             (match_operand:SI 3 "immediate_operand" "")))]
20553   "!TARGET_64BIT"
20555   if (SIBLING_CALL_P (insn))
20556     return "jmp\t%P1";
20557   else
20558     return "call\t%P1";
20560   [(set_attr "type" "callv")])
20562 (define_insn "*call_value_pop_1"
20563   [(set (match_operand 0 "" "")
20564         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20565               (match_operand:SI 2 "" "")))
20566    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20567                             (match_operand:SI 3 "immediate_operand" "i")))]
20568   "!TARGET_64BIT"
20570   if (constant_call_address_operand (operands[1], Pmode))
20571     {
20572       if (SIBLING_CALL_P (insn))
20573         return "jmp\t%P1";
20574       else
20575         return "call\t%P1";
20576     }
20577   if (SIBLING_CALL_P (insn))
20578     return "jmp\t%A1";
20579   else
20580     return "call\t%A1";
20582   [(set_attr "type" "callv")])
20584 (define_insn "*call_value_0"
20585   [(set (match_operand 0 "" "")
20586         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20587               (match_operand:SI 2 "" "")))]
20588   "!TARGET_64BIT"
20590   if (SIBLING_CALL_P (insn))
20591     return "jmp\t%P1";
20592   else
20593     return "call\t%P1";
20595   [(set_attr "type" "callv")])
20597 (define_insn "*call_value_0_rex64"
20598   [(set (match_operand 0 "" "")
20599         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20600               (match_operand:DI 2 "const_int_operand" "")))]
20601   "TARGET_64BIT"
20603   if (SIBLING_CALL_P (insn))
20604     return "jmp\t%P1";
20605   else
20606     return "call\t%P1";
20608   [(set_attr "type" "callv")])
20610 (define_insn "*call_value_1"
20611   [(set (match_operand 0 "" "")
20612         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20613               (match_operand:SI 2 "" "")))]
20614   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20616   if (constant_call_address_operand (operands[1], Pmode))
20617     return "call\t%P1";
20618   return "call\t%A1";
20620   [(set_attr "type" "callv")])
20622 (define_insn "*sibcall_value_1"
20623   [(set (match_operand 0 "" "")
20624         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20625               (match_operand:SI 2 "" "")))]
20626   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20628   if (constant_call_address_operand (operands[1], Pmode))
20629     return "jmp\t%P1";
20630   return "jmp\t%A1";
20632   [(set_attr "type" "callv")])
20634 (define_insn "*call_value_1_rex64"
20635   [(set (match_operand 0 "" "")
20636         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20637               (match_operand:DI 2 "" "")))]
20638   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20640   if (constant_call_address_operand (operands[1], Pmode))
20641     return "call\t%P1";
20642   return "call\t%A1";
20644   [(set_attr "type" "callv")])
20646 (define_insn "*sibcall_value_1_rex64"
20647   [(set (match_operand 0 "" "")
20648         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20649               (match_operand:DI 2 "" "")))]
20650   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20651   "jmp\t%P1"
20652   [(set_attr "type" "callv")])
20654 (define_insn "*sibcall_value_1_rex64_v"
20655   [(set (match_operand 0 "" "")
20656         (call (mem:QI (reg:DI R11_REG))
20657               (match_operand:DI 1 "" "")))]
20658   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20659   "jmp\t*%%r11"
20660   [(set_attr "type" "callv")])
20662 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20663 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20664 ;; caught for use by garbage collectors and the like.  Using an insn that
20665 ;; maps to SIGILL makes it more likely the program will rightfully die.
20666 ;; Keeping with tradition, "6" is in honor of #UD.
20667 (define_insn "trap"
20668   [(trap_if (const_int 1) (const_int 6))]
20669   ""
20670   { return ASM_SHORT "0x0b0f"; }
20671   [(set_attr "length" "2")])
20673 (define_expand "sse_prologue_save"
20674   [(parallel [(set (match_operand:BLK 0 "" "")
20675                    (unspec:BLK [(reg:DI 22)
20676                                 (reg:DI 23)
20677                                 (reg:DI 24)
20678                                 (reg:DI 25)
20679                                 (reg:DI 26)
20680                                 (reg:DI 27)
20681                                 (reg:DI 28)
20682                                 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20683               (use (match_operand:DI 1 "register_operand" ""))
20684               (use (match_operand:DI 2 "immediate_operand" ""))
20685               (use (label_ref:DI (match_operand 3 "" "")))])]
20686   "TARGET_64BIT"
20687   "")
20689 (define_insn "*sse_prologue_save_insn"
20690   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20691                           (match_operand:DI 4 "const_int_operand" "n")))
20692         (unspec:BLK [(reg:DI 22)
20693                      (reg:DI 23)
20694                      (reg:DI 24)
20695                      (reg:DI 25)
20696                      (reg:DI 26)
20697                      (reg:DI 27)
20698                      (reg:DI 28)
20699                      (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20700    (use (match_operand:DI 1 "register_operand" "r"))
20701    (use (match_operand:DI 2 "const_int_operand" "i"))
20702    (use (label_ref:DI (match_operand 3 "" "X")))]
20703   "TARGET_64BIT
20704    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20705    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20706   "*
20708   int i;
20709   operands[0] = gen_rtx_MEM (Pmode,
20710                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20711   output_asm_insn (\"jmp\\t%A1\", operands);
20712   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20713     {
20714       operands[4] = adjust_address (operands[0], DImode, i*16);
20715       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20716       PUT_MODE (operands[4], TImode);
20717       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20718         output_asm_insn (\"rex\", operands);
20719       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20720     }
20721   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20722                              CODE_LABEL_NUMBER (operands[3]));
20723   RET;
20725   "
20726   [(set_attr "type" "other")
20727    (set_attr "length_immediate" "0")
20728    (set_attr "length_address" "0")
20729    (set_attr "length" "135")
20730    (set_attr "memory" "store")
20731    (set_attr "modrm" "0")
20732    (set_attr "mode" "DI")])
20734 (define_expand "prefetch"
20735   [(prefetch (match_operand 0 "address_operand" "")
20736              (match_operand:SI 1 "const_int_operand" "")
20737              (match_operand:SI 2 "const_int_operand" ""))]
20738   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20740   int rw = INTVAL (operands[1]);
20741   int locality = INTVAL (operands[2]);
20743   gcc_assert (rw == 0 || rw == 1);
20744   gcc_assert (locality >= 0 && locality <= 3);
20745   gcc_assert (GET_MODE (operands[0]) == Pmode
20746               || GET_MODE (operands[0]) == VOIDmode);
20748   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20749      supported by SSE counterpart or the SSE prefetch is not available
20750      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20751      of locality.  */
20752   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20753     operands[2] = GEN_INT (3);
20754   else
20755     operands[1] = const0_rtx;
20758 (define_insn "*prefetch_sse"
20759   [(prefetch (match_operand:SI 0 "address_operand" "p")
20760              (const_int 0)
20761              (match_operand:SI 1 "const_int_operand" ""))]
20762   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20764   static const char * const patterns[4] = {
20765    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20766   };
20768   int locality = INTVAL (operands[1]);
20769   gcc_assert (locality >= 0 && locality <= 3);
20771   return patterns[locality];  
20773   [(set_attr "type" "sse")
20774    (set_attr "memory" "none")])
20776 (define_insn "*prefetch_sse_rex"
20777   [(prefetch (match_operand:DI 0 "address_operand" "p")
20778              (const_int 0)
20779              (match_operand:SI 1 "const_int_operand" ""))]
20780   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20782   static const char * const patterns[4] = {
20783    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20784   };
20786   int locality = INTVAL (operands[1]);
20787   gcc_assert (locality >= 0 && locality <= 3);
20789   return patterns[locality];  
20791   [(set_attr "type" "sse")
20792    (set_attr "memory" "none")])
20794 (define_insn "*prefetch_3dnow"
20795   [(prefetch (match_operand:SI 0 "address_operand" "p")
20796              (match_operand:SI 1 "const_int_operand" "n")
20797              (const_int 3))]
20798   "TARGET_3DNOW && !TARGET_64BIT"
20800   if (INTVAL (operands[1]) == 0)
20801     return "prefetch\t%a0";
20802   else
20803     return "prefetchw\t%a0";
20805   [(set_attr "type" "mmx")
20806    (set_attr "memory" "none")])
20808 (define_insn "*prefetch_3dnow_rex"
20809   [(prefetch (match_operand:DI 0 "address_operand" "p")
20810              (match_operand:SI 1 "const_int_operand" "n")
20811              (const_int 3))]
20812   "TARGET_3DNOW && TARGET_64BIT"
20814   if (INTVAL (operands[1]) == 0)
20815     return "prefetch\t%a0";
20816   else
20817     return "prefetchw\t%a0";
20819   [(set_attr "type" "mmx")
20820    (set_attr "memory" "none")])
20822 (define_expand "stack_protect_set"
20823   [(match_operand 0 "memory_operand" "")
20824    (match_operand 1 "memory_operand" "")]
20825   ""
20827 #ifdef TARGET_THREAD_SSP_OFFSET
20828   if (TARGET_64BIT)
20829     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20830                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20831   else
20832     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20833                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20834 #else
20835   if (TARGET_64BIT)
20836     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20837   else
20838     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20839 #endif
20840   DONE;
20843 (define_insn "stack_protect_set_si"
20844   [(set (match_operand:SI 0 "memory_operand" "=m")
20845         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20846    (set (match_scratch:SI 2 "=&r") (const_int 0))
20847    (clobber (reg:CC FLAGS_REG))]
20848   ""
20849   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20850   [(set_attr "type" "multi")])
20852 (define_insn "stack_protect_set_di"
20853   [(set (match_operand:DI 0 "memory_operand" "=m")
20854         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20855    (set (match_scratch:DI 2 "=&r") (const_int 0))
20856    (clobber (reg:CC FLAGS_REG))]
20857   "TARGET_64BIT"
20858   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20859   [(set_attr "type" "multi")])
20861 (define_insn "stack_tls_protect_set_si"
20862   [(set (match_operand:SI 0 "memory_operand" "=m")
20863         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20864    (set (match_scratch:SI 2 "=&r") (const_int 0))
20865    (clobber (reg:CC FLAGS_REG))]
20866   ""
20867   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20868   [(set_attr "type" "multi")])
20870 (define_insn "stack_tls_protect_set_di"
20871   [(set (match_operand:DI 0 "memory_operand" "=m")
20872         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20873    (set (match_scratch:DI 2 "=&r") (const_int 0))
20874    (clobber (reg:CC FLAGS_REG))]
20875   "TARGET_64BIT"
20876   {
20877      /* The kernel uses a different segment register for performance reasons; a
20878         system call would not have to trash the userspace segment register,
20879         which would be expensive */
20880      if (ix86_cmodel != CM_KERNEL)
20881         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20882      else
20883         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20884   }
20885   [(set_attr "type" "multi")])
20887 (define_expand "stack_protect_test"
20888   [(match_operand 0 "memory_operand" "")
20889    (match_operand 1 "memory_operand" "")
20890    (match_operand 2 "" "")]
20891   ""
20893   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20894   ix86_compare_op0 = operands[0];
20895   ix86_compare_op1 = operands[1];
20896   ix86_compare_emitted = flags;
20898 #ifdef TARGET_THREAD_SSP_OFFSET
20899   if (TARGET_64BIT)
20900     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20901                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20902   else
20903     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20904                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20905 #else
20906   if (TARGET_64BIT)
20907     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20908   else
20909     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20910 #endif
20911   emit_jump_insn (gen_beq (operands[2]));
20912   DONE;
20915 (define_insn "stack_protect_test_si"
20916   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20917         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20918                      (match_operand:SI 2 "memory_operand" "m")]
20919                     UNSPEC_SP_TEST))
20920    (clobber (match_scratch:SI 3 "=&r"))]
20921   ""
20922   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20923   [(set_attr "type" "multi")])
20925 (define_insn "stack_protect_test_di"
20926   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20927         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20928                      (match_operand:DI 2 "memory_operand" "m")]
20929                     UNSPEC_SP_TEST))
20930    (clobber (match_scratch:DI 3 "=&r"))]
20931   "TARGET_64BIT"
20932   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20933   [(set_attr "type" "multi")])
20935 (define_insn "stack_tls_protect_test_si"
20936   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20937         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20938                      (match_operand:SI 2 "const_int_operand" "i")]
20939                     UNSPEC_SP_TLS_TEST))
20940    (clobber (match_scratch:SI 3 "=r"))]
20941   ""
20942   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20943   [(set_attr "type" "multi")])
20945 (define_insn "stack_tls_protect_test_di"
20946   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20947         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20948                      (match_operand:DI 2 "const_int_operand" "i")]
20949                     UNSPEC_SP_TLS_TEST))
20950    (clobber (match_scratch:DI 3 "=r"))]
20951   "TARGET_64BIT"
20952   {
20953      /* The kernel uses a different segment register for performance reasons; a
20954         system call would not have to trash the userspace segment register,
20955         which would be expensive */
20956      if (ix86_cmodel != CM_KERNEL)
20957         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20958      else
20959         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20960   }
20961   [(set_attr "type" "multi")])
20963 (include "mmx.md")
20964 (include "sse.md")
20965 (include "sync.md")