2006-11-18 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / config / i386 / i386.md
blob458ca0f2ba08b91453f5aa5f528e69667257fffb
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,core2,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        || standard_80387_constant_p (operands[1])
2791        || GET_CODE (operands[1]) != CONST_DOUBLE
2792        || memory_operand (operands[0], XFmode))"
2794   switch (which_alternative)
2795     {
2796     case 0:
2797       return output_387_reg_move (insn, operands);
2799     case 1:
2800       /* There is no non-popping store to memory for XFmode.  So if
2801          we need one, follow the store with a load.  */
2802       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2803         return "fstp%z0\t%y0\;fld%z0\t%y0";
2804       else
2805         return "fstp%z0\t%y0";
2807     case 2:
2808       return standard_80387_constant_opcode (operands[1]);
2810     case 3: case 4:
2811       return "#";
2812     default:
2813       gcc_unreachable ();
2814     }
2816   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2817    (set_attr "mode" "XF,XF,XF,SI,SI")])
2819 (define_insn "*movxf_integer"
2820   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2821         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2822   "!optimize_size
2823    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2824    && (reload_in_progress || reload_completed
2825        || standard_80387_constant_p (operands[1])
2826        || GET_CODE (operands[1]) != CONST_DOUBLE
2827        || memory_operand (operands[0], XFmode))"
2829   switch (which_alternative)
2830     {
2831     case 0:
2832       return output_387_reg_move (insn, operands);
2834     case 1:
2835       /* There is no non-popping store to memory for XFmode.  So if
2836          we need one, follow the store with a load.  */
2837       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2838         return "fstp%z0\t%y0\;fld%z0\t%y0";
2839       else
2840         return "fstp%z0\t%y0";
2842     case 2:
2843       return standard_80387_constant_opcode (operands[1]);
2845     case 3: case 4:
2846       return "#";
2848     default:
2849       gcc_unreachable ();
2850     }
2852   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2853    (set_attr "mode" "XF,XF,XF,SI,SI")])
2855 (define_split
2856   [(set (match_operand 0 "nonimmediate_operand" "")
2857         (match_operand 1 "general_operand" ""))]
2858   "reload_completed
2859    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2860    && GET_MODE (operands[0]) == XFmode
2861    && ! (ANY_FP_REG_P (operands[0]) ||
2862          (GET_CODE (operands[0]) == SUBREG
2863           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2864    && ! (ANY_FP_REG_P (operands[1]) ||
2865          (GET_CODE (operands[1]) == SUBREG
2866           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2867   [(const_int 0)]
2868   "ix86_split_long_move (operands); DONE;")
2870 (define_split
2871   [(set (match_operand 0 "register_operand" "")
2872         (match_operand 1 "memory_operand" ""))]
2873   "reload_completed
2874    && GET_CODE (operands[1]) == MEM
2875    && (GET_MODE (operands[0]) == XFmode
2876        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2877    && constant_pool_reference_p (operands[1])"
2878   [(set (match_dup 0) (match_dup 1))]
2880   rtx c = avoid_constant_pool_reference (operands[1]);
2881   rtx r = operands[0];
2883   if (GET_CODE (r) == SUBREG)
2884     r = SUBREG_REG (r);
2886   if (SSE_REG_P (r))
2887     {
2888       if (!standard_sse_constant_p (c))
2889         FAIL;
2890     }
2891   else if (FP_REG_P (r))
2892     {
2893       if (!standard_80387_constant_p (c))
2894         FAIL;
2895     }
2896   else if (MMX_REG_P (r))
2897     FAIL;
2899   operands[1] = c;
2902 (define_insn "swapxf"
2903   [(set (match_operand:XF 0 "register_operand" "+f")
2904         (match_operand:XF 1 "register_operand" "+f"))
2905    (set (match_dup 1)
2906         (match_dup 0))]
2907   "TARGET_80387"
2909   if (STACK_TOP_P (operands[0]))
2910     return "fxch\t%1";
2911   else
2912     return "fxch\t%0";
2914   [(set_attr "type" "fxch")
2915    (set_attr "mode" "XF")])
2917 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2918 (define_split
2919   [(set (match_operand:X87MODEF 0 "register_operand" "")
2920         (match_operand:X87MODEF 1 "immediate_operand" ""))]
2921   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2922    && (standard_80387_constant_p (operands[1]) == 8
2923        || standard_80387_constant_p (operands[1]) == 9)"
2924   [(set (match_dup 0)(match_dup 1))
2925    (set (match_dup 0)
2926         (neg:X87MODEF (match_dup 0)))]
2928   REAL_VALUE_TYPE r;
2930   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2931   if (real_isnegzero (&r))
2932     operands[1] = CONST0_RTX (<MODE>mode);
2933   else
2934     operands[1] = CONST1_RTX (<MODE>mode);
2937 (define_expand "movtf"
2938   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2939         (match_operand:TF 1 "nonimmediate_operand" ""))]
2940   "TARGET_64BIT"
2942   ix86_expand_move (TFmode, operands);
2943   DONE;
2946 (define_insn "*movtf_internal"
2947   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2948         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2949   "TARGET_64BIT
2950    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2952   switch (which_alternative)
2953     {
2954     case 0:
2955     case 1:
2956       return "#";
2957     case 2:
2958       if (get_attr_mode (insn) == MODE_V4SF)
2959         return "xorps\t%0, %0";
2960       else
2961         return "pxor\t%0, %0";
2962     case 3:
2963     case 4:
2964       if (get_attr_mode (insn) == MODE_V4SF)
2965         return "movaps\t{%1, %0|%0, %1}";
2966       else
2967         return "movdqa\t{%1, %0|%0, %1}";
2968     default:
2969       gcc_unreachable ();
2970     }
2972   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2973    (set (attr "mode")
2974         (cond [(eq_attr "alternative" "2,3")
2975                  (if_then_else
2976                    (ne (symbol_ref "optimize_size")
2977                        (const_int 0))
2978                    (const_string "V4SF")
2979                    (const_string "TI"))
2980                (eq_attr "alternative" "4")
2981                  (if_then_else
2982                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2983                             (const_int 0))
2984                         (ne (symbol_ref "optimize_size")
2985                             (const_int 0)))
2986                    (const_string "V4SF")
2987                    (const_string "TI"))]
2988                (const_string "DI")))])
2990 (define_split
2991   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2992         (match_operand:TF 1 "general_operand" ""))]
2993   "reload_completed && !SSE_REG_P (operands[0])
2994    && !SSE_REG_P (operands[1])"
2995   [(const_int 0)]
2996   "ix86_split_long_move (operands); DONE;")
2998 ;; Zero extension instructions
3000 (define_expand "zero_extendhisi2"
3001   [(set (match_operand:SI 0 "register_operand" "")
3002      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3003   ""
3005   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3006     {
3007       operands[1] = force_reg (HImode, operands[1]);
3008       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3009       DONE;
3010     }
3013 (define_insn "zero_extendhisi2_and"
3014   [(set (match_operand:SI 0 "register_operand" "=r")
3015      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3016    (clobber (reg:CC FLAGS_REG))]
3017   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3018   "#"
3019   [(set_attr "type" "alu1")
3020    (set_attr "mode" "SI")])
3022 (define_split
3023   [(set (match_operand:SI 0 "register_operand" "")
3024         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3025    (clobber (reg:CC FLAGS_REG))]
3026   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3027   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3028               (clobber (reg:CC FLAGS_REG))])]
3029   "")
3031 (define_insn "*zero_extendhisi2_movzwl"
3032   [(set (match_operand:SI 0 "register_operand" "=r")
3033      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3034   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3035   "movz{wl|x}\t{%1, %0|%0, %1}"
3036   [(set_attr "type" "imovx")
3037    (set_attr "mode" "SI")])
3039 (define_expand "zero_extendqihi2"
3040   [(parallel
3041     [(set (match_operand:HI 0 "register_operand" "")
3042        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3043      (clobber (reg:CC FLAGS_REG))])]
3044   ""
3045   "")
3047 (define_insn "*zero_extendqihi2_and"
3048   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3049      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3050    (clobber (reg:CC FLAGS_REG))]
3051   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3052   "#"
3053   [(set_attr "type" "alu1")
3054    (set_attr "mode" "HI")])
3056 (define_insn "*zero_extendqihi2_movzbw_and"
3057   [(set (match_operand:HI 0 "register_operand" "=r,r")
3058      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3059    (clobber (reg:CC FLAGS_REG))]
3060   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3061   "#"
3062   [(set_attr "type" "imovx,alu1")
3063    (set_attr "mode" "HI")])
3065 ; zero extend to SImode here to avoid partial register stalls
3066 (define_insn "*zero_extendqihi2_movzbl"
3067   [(set (match_operand:HI 0 "register_operand" "=r")
3068      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3069   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3070   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3071   [(set_attr "type" "imovx")
3072    (set_attr "mode" "SI")])
3074 ;; For the movzbw case strip only the clobber
3075 (define_split
3076   [(set (match_operand:HI 0 "register_operand" "")
3077         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3078    (clobber (reg:CC FLAGS_REG))]
3079   "reload_completed
3080    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3081    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3082   [(set (match_operand:HI 0 "register_operand" "")
3083         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3085 ;; When source and destination does not overlap, clear destination
3086 ;; first and then do the movb
3087 (define_split
3088   [(set (match_operand:HI 0 "register_operand" "")
3089         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3090    (clobber (reg:CC FLAGS_REG))]
3091   "reload_completed
3092    && ANY_QI_REG_P (operands[0])
3093    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3094    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3095   [(set (match_dup 0) (const_int 0))
3096    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3097   "operands[2] = gen_lowpart (QImode, operands[0]);")
3099 ;; Rest is handled by single and.
3100 (define_split
3101   [(set (match_operand:HI 0 "register_operand" "")
3102         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3103    (clobber (reg:CC FLAGS_REG))]
3104   "reload_completed
3105    && true_regnum (operands[0]) == true_regnum (operands[1])"
3106   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3107               (clobber (reg:CC FLAGS_REG))])]
3108   "")
3110 (define_expand "zero_extendqisi2"
3111   [(parallel
3112     [(set (match_operand:SI 0 "register_operand" "")
3113        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3114      (clobber (reg:CC FLAGS_REG))])]
3115   ""
3116   "")
3118 (define_insn "*zero_extendqisi2_and"
3119   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3120      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3121    (clobber (reg:CC FLAGS_REG))]
3122   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3123   "#"
3124   [(set_attr "type" "alu1")
3125    (set_attr "mode" "SI")])
3127 (define_insn "*zero_extendqisi2_movzbw_and"
3128   [(set (match_operand:SI 0 "register_operand" "=r,r")
3129      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3130    (clobber (reg:CC FLAGS_REG))]
3131   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3132   "#"
3133   [(set_attr "type" "imovx,alu1")
3134    (set_attr "mode" "SI")])
3136 (define_insn "*zero_extendqisi2_movzbw"
3137   [(set (match_operand:SI 0 "register_operand" "=r")
3138      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3139   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3140   "movz{bl|x}\t{%1, %0|%0, %1}"
3141   [(set_attr "type" "imovx")
3142    (set_attr "mode" "SI")])
3144 ;; For the movzbl case strip only the clobber
3145 (define_split
3146   [(set (match_operand:SI 0 "register_operand" "")
3147         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3148    (clobber (reg:CC FLAGS_REG))]
3149   "reload_completed
3150    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3151    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3152   [(set (match_dup 0)
3153         (zero_extend:SI (match_dup 1)))])
3155 ;; When source and destination does not overlap, clear destination
3156 ;; first and then do the movb
3157 (define_split
3158   [(set (match_operand:SI 0 "register_operand" "")
3159         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3160    (clobber (reg:CC FLAGS_REG))]
3161   "reload_completed
3162    && ANY_QI_REG_P (operands[0])
3163    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3164    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3165    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3166   [(set (match_dup 0) (const_int 0))
3167    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3168   "operands[2] = gen_lowpart (QImode, operands[0]);")
3170 ;; Rest is handled by single and.
3171 (define_split
3172   [(set (match_operand:SI 0 "register_operand" "")
3173         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3174    (clobber (reg:CC FLAGS_REG))]
3175   "reload_completed
3176    && true_regnum (operands[0]) == true_regnum (operands[1])"
3177   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3178               (clobber (reg:CC FLAGS_REG))])]
3179   "")
3181 ;; %%% Kill me once multi-word ops are sane.
3182 (define_expand "zero_extendsidi2"
3183   [(set (match_operand:DI 0 "register_operand" "=r")
3184      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3185   ""
3186   "if (!TARGET_64BIT)
3187      {
3188        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3189        DONE;
3190      }
3191   ")
3193 (define_insn "zero_extendsidi2_32"
3194   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3195         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3196    (clobber (reg:CC FLAGS_REG))]
3197   "!TARGET_64BIT"
3198   "@
3199    #
3200    #
3201    #
3202    movd\t{%1, %0|%0, %1}
3203    movd\t{%1, %0|%0, %1}"
3204   [(set_attr "mode" "SI,SI,SI,DI,TI")
3205    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3207 (define_insn "zero_extendsidi2_rex64"
3208   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3209      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3210   "TARGET_64BIT"
3211   "@
3212    mov\t{%k1, %k0|%k0, %k1}
3213    #
3214    movd\t{%1, %0|%0, %1}
3215    movd\t{%1, %0|%0, %1}"
3216   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3217    (set_attr "mode" "SI,DI,SI,SI")])
3219 (define_split
3220   [(set (match_operand:DI 0 "memory_operand" "")
3221      (zero_extend:DI (match_dup 0)))]
3222   "TARGET_64BIT"
3223   [(set (match_dup 4) (const_int 0))]
3224   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3226 (define_split
3227   [(set (match_operand:DI 0 "register_operand" "")
3228         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3229    (clobber (reg:CC FLAGS_REG))]
3230   "!TARGET_64BIT && reload_completed
3231    && true_regnum (operands[0]) == true_regnum (operands[1])"
3232   [(set (match_dup 4) (const_int 0))]
3233   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3235 (define_split
3236   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3237         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3238    (clobber (reg:CC FLAGS_REG))]
3239   "!TARGET_64BIT && reload_completed
3240    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3241   [(set (match_dup 3) (match_dup 1))
3242    (set (match_dup 4) (const_int 0))]
3243   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3245 (define_insn "zero_extendhidi2"
3246   [(set (match_operand:DI 0 "register_operand" "=r")
3247      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3248   "TARGET_64BIT"
3249   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3250   [(set_attr "type" "imovx")
3251    (set_attr "mode" "DI")])
3253 (define_insn "zero_extendqidi2"
3254   [(set (match_operand:DI 0 "register_operand" "=r")
3255      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3256   "TARGET_64BIT"
3257   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3258   [(set_attr "type" "imovx")
3259    (set_attr "mode" "DI")])
3261 ;; Sign extension instructions
3263 (define_expand "extendsidi2"
3264   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3265                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3266               (clobber (reg:CC FLAGS_REG))
3267               (clobber (match_scratch:SI 2 ""))])]
3268   ""
3270   if (TARGET_64BIT)
3271     {
3272       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3273       DONE;
3274     }
3277 (define_insn "*extendsidi2_1"
3278   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3279         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3280    (clobber (reg:CC FLAGS_REG))
3281    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3282   "!TARGET_64BIT"
3283   "#")
3285 (define_insn "extendsidi2_rex64"
3286   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3287         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3288   "TARGET_64BIT"
3289   "@
3290    {cltq|cdqe}
3291    movs{lq|x}\t{%1,%0|%0, %1}"
3292   [(set_attr "type" "imovx")
3293    (set_attr "mode" "DI")
3294    (set_attr "prefix_0f" "0")
3295    (set_attr "modrm" "0,1")])
3297 (define_insn "extendhidi2"
3298   [(set (match_operand:DI 0 "register_operand" "=r")
3299         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3300   "TARGET_64BIT"
3301   "movs{wq|x}\t{%1,%0|%0, %1}"
3302   [(set_attr "type" "imovx")
3303    (set_attr "mode" "DI")])
3305 (define_insn "extendqidi2"
3306   [(set (match_operand:DI 0 "register_operand" "=r")
3307         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3308   "TARGET_64BIT"
3309   "movs{bq|x}\t{%1,%0|%0, %1}"
3310    [(set_attr "type" "imovx")
3311     (set_attr "mode" "DI")])
3313 ;; Extend to memory case when source register does die.
3314 (define_split
3315   [(set (match_operand:DI 0 "memory_operand" "")
3316         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3317    (clobber (reg:CC FLAGS_REG))
3318    (clobber (match_operand:SI 2 "register_operand" ""))]
3319   "(reload_completed
3320     && dead_or_set_p (insn, operands[1])
3321     && !reg_mentioned_p (operands[1], operands[0]))"
3322   [(set (match_dup 3) (match_dup 1))
3323    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3324               (clobber (reg:CC FLAGS_REG))])
3325    (set (match_dup 4) (match_dup 1))]
3326   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3328 ;; Extend to memory case when source register does not die.
3329 (define_split
3330   [(set (match_operand:DI 0 "memory_operand" "")
3331         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332    (clobber (reg:CC FLAGS_REG))
3333    (clobber (match_operand:SI 2 "register_operand" ""))]
3334   "reload_completed"
3335   [(const_int 0)]
3337   split_di (&operands[0], 1, &operands[3], &operands[4]);
3339   emit_move_insn (operands[3], operands[1]);
3341   /* Generate a cltd if possible and doing so it profitable.  */
3342   if (true_regnum (operands[1]) == 0
3343       && true_regnum (operands[2]) == 1
3344       && (optimize_size || TARGET_USE_CLTD))
3345     {
3346       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3347     }
3348   else
3349     {
3350       emit_move_insn (operands[2], operands[1]);
3351       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3352     }
3353   emit_move_insn (operands[4], operands[2]);
3354   DONE;
3357 ;; Extend to register case.  Optimize case where source and destination
3358 ;; registers match and cases where we can use cltd.
3359 (define_split
3360   [(set (match_operand:DI 0 "register_operand" "")
3361         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3362    (clobber (reg:CC FLAGS_REG))
3363    (clobber (match_scratch:SI 2 ""))]
3364   "reload_completed"
3365   [(const_int 0)]
3367   split_di (&operands[0], 1, &operands[3], &operands[4]);
3369   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3370     emit_move_insn (operands[3], operands[1]);
3372   /* Generate a cltd if possible and doing so it profitable.  */
3373   if (true_regnum (operands[3]) == 0
3374       && (optimize_size || TARGET_USE_CLTD))
3375     {
3376       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3377       DONE;
3378     }
3380   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3381     emit_move_insn (operands[4], operands[1]);
3383   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3384   DONE;
3387 (define_insn "extendhisi2"
3388   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3389         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3390   ""
3392   switch (get_attr_prefix_0f (insn))
3393     {
3394     case 0:
3395       return "{cwtl|cwde}";
3396     default:
3397       return "movs{wl|x}\t{%1,%0|%0, %1}";
3398     }
3400   [(set_attr "type" "imovx")
3401    (set_attr "mode" "SI")
3402    (set (attr "prefix_0f")
3403      ;; movsx is short decodable while cwtl is vector decoded.
3404      (if_then_else (and (eq_attr "cpu" "!k6")
3405                         (eq_attr "alternative" "0"))
3406         (const_string "0")
3407         (const_string "1")))
3408    (set (attr "modrm")
3409      (if_then_else (eq_attr "prefix_0f" "0")
3410         (const_string "0")
3411         (const_string "1")))])
3413 (define_insn "*extendhisi2_zext"
3414   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3415         (zero_extend:DI
3416           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3417   "TARGET_64BIT"
3419   switch (get_attr_prefix_0f (insn))
3420     {
3421     case 0:
3422       return "{cwtl|cwde}";
3423     default:
3424       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3425     }
3427   [(set_attr "type" "imovx")
3428    (set_attr "mode" "SI")
3429    (set (attr "prefix_0f")
3430      ;; movsx is short decodable while cwtl is vector decoded.
3431      (if_then_else (and (eq_attr "cpu" "!k6")
3432                         (eq_attr "alternative" "0"))
3433         (const_string "0")
3434         (const_string "1")))
3435    (set (attr "modrm")
3436      (if_then_else (eq_attr "prefix_0f" "0")
3437         (const_string "0")
3438         (const_string "1")))])
3440 (define_insn "extendqihi2"
3441   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3442         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3443   ""
3445   switch (get_attr_prefix_0f (insn))
3446     {
3447     case 0:
3448       return "{cbtw|cbw}";
3449     default:
3450       return "movs{bw|x}\t{%1,%0|%0, %1}";
3451     }
3453   [(set_attr "type" "imovx")
3454    (set_attr "mode" "HI")
3455    (set (attr "prefix_0f")
3456      ;; movsx is short decodable while cwtl is vector decoded.
3457      (if_then_else (and (eq_attr "cpu" "!k6")
3458                         (eq_attr "alternative" "0"))
3459         (const_string "0")
3460         (const_string "1")))
3461    (set (attr "modrm")
3462      (if_then_else (eq_attr "prefix_0f" "0")
3463         (const_string "0")
3464         (const_string "1")))])
3466 (define_insn "extendqisi2"
3467   [(set (match_operand:SI 0 "register_operand" "=r")
3468         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3469   ""
3470   "movs{bl|x}\t{%1,%0|%0, %1}"
3471    [(set_attr "type" "imovx")
3472     (set_attr "mode" "SI")])
3474 (define_insn "*extendqisi2_zext"
3475   [(set (match_operand:DI 0 "register_operand" "=r")
3476         (zero_extend:DI
3477           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3478   "TARGET_64BIT"
3479   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3480    [(set_attr "type" "imovx")
3481     (set_attr "mode" "SI")])
3483 ;; Conversions between float and double.
3485 ;; These are all no-ops in the model used for the 80387.  So just
3486 ;; emit moves.
3488 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3489 (define_insn "*dummy_extendsfdf2"
3490   [(set (match_operand:DF 0 "push_operand" "=<")
3491         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3492   "0"
3493   "#")
3495 (define_split
3496   [(set (match_operand:DF 0 "push_operand" "")
3497         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3498   "!TARGET_64BIT"
3499   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3500    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3502 (define_split
3503   [(set (match_operand:DF 0 "push_operand" "")
3504         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3505   "TARGET_64BIT"
3506   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3507    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3509 (define_insn "*dummy_extendsfxf2"
3510   [(set (match_operand:XF 0 "push_operand" "=<")
3511         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3512   "0"
3513   "#")
3515 (define_split
3516   [(set (match_operand:XF 0 "push_operand" "")
3517         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3518   ""
3519   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3520    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3521   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3523 (define_split
3524   [(set (match_operand:XF 0 "push_operand" "")
3525         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3526   "TARGET_64BIT"
3527   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3528    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3529   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3531 (define_split
3532   [(set (match_operand:XF 0 "push_operand" "")
3533         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3534   ""
3535   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3536    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3537   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3539 (define_split
3540   [(set (match_operand:XF 0 "push_operand" "")
3541         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3542   "TARGET_64BIT"
3543   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3544    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3545   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3547 (define_expand "extendsfdf2"
3548   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3549         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3550   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3552   /* ??? Needed for compress_float_constant since all fp constants
3553      are LEGITIMATE_CONSTANT_P.  */
3554   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3555     {
3556       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3557           && standard_80387_constant_p (operands[1]) > 0)
3558         {
3559           operands[1] = simplify_const_unary_operation
3560             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3561           emit_move_insn_1 (operands[0], operands[1]);
3562           DONE;
3563         }
3564       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3565     }
3568 (define_insn "*extendsfdf2_mixed"
3569   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3570         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3571   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3573   switch (which_alternative)
3574     {
3575     case 0:
3576       return output_387_reg_move (insn, operands);
3578     case 1:
3579       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3580         return "fstp%z0\t%y0";
3581       else
3582         return "fst%z0\t%y0";
3584     case 2:
3585       return "cvtss2sd\t{%1, %0|%0, %1}";
3587     default:
3588       gcc_unreachable ();
3589     }
3591   [(set_attr "type" "fmov,fmov,ssecvt")
3592    (set_attr "mode" "SF,XF,DF")])
3594 (define_insn "*extendsfdf2_sse"
3595   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3596         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3597   "TARGET_SSE2 && TARGET_SSE_MATH"
3598   "cvtss2sd\t{%1, %0|%0, %1}"
3599   [(set_attr "type" "ssecvt")
3600    (set_attr "mode" "DF")])
3602 (define_insn "*extendsfdf2_i387"
3603   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3604         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3605   "TARGET_80387"
3607   switch (which_alternative)
3608     {
3609     case 0:
3610       return output_387_reg_move (insn, operands);
3612     case 1:
3613       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3614         return "fstp%z0\t%y0";
3615       else
3616         return "fst%z0\t%y0";
3618     default:
3619       gcc_unreachable ();
3620     }
3622   [(set_attr "type" "fmov")
3623    (set_attr "mode" "SF,XF")])
3625 (define_expand "extendsfxf2"
3626   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3627         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3628   "TARGET_80387"
3630   /* ??? Needed for compress_float_constant since all fp constants
3631      are LEGITIMATE_CONSTANT_P.  */
3632   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3633     {
3634       if (standard_80387_constant_p (operands[1]) > 0)
3635         {
3636           operands[1] = simplify_const_unary_operation
3637             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3638           emit_move_insn_1 (operands[0], operands[1]);
3639           DONE;
3640         }
3641       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3642     }
3645 (define_insn "*extendsfxf2_i387"
3646   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3647         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3648   "TARGET_80387"
3650   switch (which_alternative)
3651     {
3652     case 0:
3653       return output_387_reg_move (insn, operands);
3655     case 1:
3656       /* There is no non-popping store to memory for XFmode.  So if
3657          we need one, follow the store with a load.  */
3658       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3659         return "fstp%z0\t%y0";
3660       else
3661         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3663     default:
3664       gcc_unreachable ();
3665     }
3667   [(set_attr "type" "fmov")
3668    (set_attr "mode" "SF,XF")])
3670 (define_expand "extenddfxf2"
3671   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3672         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3673   "TARGET_80387"
3675   /* ??? Needed for compress_float_constant since all fp constants
3676      are LEGITIMATE_CONSTANT_P.  */
3677   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3678     {
3679       if (standard_80387_constant_p (operands[1]) > 0)
3680         {
3681           operands[1] = simplify_const_unary_operation
3682             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3683           emit_move_insn_1 (operands[0], operands[1]);
3684           DONE;
3685         }
3686       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3687     }
3690 (define_insn "*extenddfxf2_i387"
3691   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3692         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3693   "TARGET_80387"
3695   switch (which_alternative)
3696     {
3697     case 0:
3698       return output_387_reg_move (insn, operands);
3700     case 1:
3701       /* There is no non-popping store to memory for XFmode.  So if
3702          we need one, follow the store with a load.  */
3703       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3704         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3705       else
3706         return "fstp%z0\t%y0";
3708     default:
3709       gcc_unreachable ();
3710     }
3712   [(set_attr "type" "fmov")
3713    (set_attr "mode" "DF,XF")])
3715 ;; %%% This seems bad bad news.
3716 ;; This cannot output into an f-reg because there is no way to be sure
3717 ;; of truncating in that case.  Otherwise this is just like a simple move
3718 ;; insn.  So we pretend we can output to a reg in order to get better
3719 ;; register preferencing, but we really use a stack slot.
3721 ;; Conversion from DFmode to SFmode.
3723 (define_expand "truncdfsf2"
3724   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3725         (float_truncate:SF
3726           (match_operand:DF 1 "nonimmediate_operand" "")))]
3727   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3729   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3730     ;
3731   else if (flag_unsafe_math_optimizations)
3732     ;
3733   else
3734     {
3735       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3736       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3737       DONE;
3738     }
3741 (define_expand "truncdfsf2_with_temp"
3742   [(parallel [(set (match_operand:SF 0 "" "")
3743                    (float_truncate:SF (match_operand:DF 1 "" "")))
3744               (clobber (match_operand:SF 2 "" ""))])]
3745   "")
3747 (define_insn "*truncdfsf_fast_mixed"
3748   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3749         (float_truncate:SF
3750           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3751   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3753   switch (which_alternative)
3754     {
3755     case 0:
3756       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3757         return "fstp%z0\t%y0";
3758       else
3759         return "fst%z0\t%y0";
3760     case 1:
3761       return output_387_reg_move (insn, operands);
3762     case 2:
3763       return "cvtsd2ss\t{%1, %0|%0, %1}";
3764     default:
3765       gcc_unreachable ();
3766     }
3768   [(set_attr "type" "fmov,fmov,ssecvt")
3769    (set_attr "mode" "SF")])
3771 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3772 ;; because nothing we do here is unsafe.
3773 (define_insn "*truncdfsf_fast_sse"
3774   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3775         (float_truncate:SF
3776           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3777   "TARGET_SSE2 && TARGET_SSE_MATH"
3778   "cvtsd2ss\t{%1, %0|%0, %1}"
3779   [(set_attr "type" "ssecvt")
3780    (set_attr "mode" "SF")])
3782 (define_insn "*truncdfsf_fast_i387"
3783   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3784         (float_truncate:SF
3785           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3786   "TARGET_80387 && flag_unsafe_math_optimizations"
3787   "* return output_387_reg_move (insn, operands);"
3788   [(set_attr "type" "fmov")
3789    (set_attr "mode" "SF")])
3791 (define_insn "*truncdfsf_mixed"
3792   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3793         (float_truncate:SF
3794           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3795    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3796   "TARGET_MIX_SSE_I387"
3798   switch (which_alternative)
3799     {
3800     case 0:
3801       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3802         return "fstp%z0\t%y0";
3803       else
3804         return "fst%z0\t%y0";
3805     case 1:
3806       return "#";
3807     case 2:
3808       return "cvtsd2ss\t{%1, %0|%0, %1}";
3809     default:
3810       gcc_unreachable ();
3811     }
3813   [(set_attr "type" "fmov,multi,ssecvt")
3814    (set_attr "unit" "*,i387,*")
3815    (set_attr "mode" "SF")])
3817 (define_insn "*truncdfsf_i387"
3818   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3819         (float_truncate:SF
3820           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3821    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3822   "TARGET_80387"
3824   switch (which_alternative)
3825     {
3826     case 0:
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";
3831     case 1:
3832       return "#";
3833     default:
3834       gcc_unreachable ();
3835     }
3837   [(set_attr "type" "fmov,multi")
3838    (set_attr "unit" "*,i387")
3839    (set_attr "mode" "SF")])
3841 (define_insn "*truncdfsf2_i387_1"
3842   [(set (match_operand:SF 0 "memory_operand" "=m")
3843         (float_truncate:SF
3844           (match_operand:DF 1 "register_operand" "f")))]
3845   "TARGET_80387
3846    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3847    && !TARGET_MIX_SSE_I387"
3849   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3850     return "fstp%z0\t%y0";
3851   else
3852     return "fst%z0\t%y0";
3854   [(set_attr "type" "fmov")
3855    (set_attr "mode" "SF")])
3857 (define_split
3858   [(set (match_operand:SF 0 "register_operand" "")
3859         (float_truncate:SF
3860          (match_operand:DF 1 "fp_register_operand" "")))
3861    (clobber (match_operand 2 "" ""))]
3862   "reload_completed"
3863   [(set (match_dup 2) (match_dup 1))
3864    (set (match_dup 0) (match_dup 2))]
3866   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3869 ;; Conversion from XFmode to SFmode.
3871 (define_expand "truncxfsf2"
3872   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3873                    (float_truncate:SF
3874                     (match_operand:XF 1 "register_operand" "")))
3875               (clobber (match_dup 2))])]
3876   "TARGET_80387"
3878   if (flag_unsafe_math_optimizations)
3879     {
3880       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3881       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3882       if (reg != operands[0])
3883         emit_move_insn (operands[0], reg);
3884       DONE;
3885     }
3886   else
3887     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3890 (define_insn "*truncxfsf2_mixed"
3891   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3892         (float_truncate:SF
3893          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3894    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3895   "TARGET_MIX_SSE_I387"
3897   gcc_assert (!which_alternative);
3898   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3899     return "fstp%z0\t%y0";
3900   else
3901     return "fst%z0\t%y0";
3903   [(set_attr "type" "fmov,multi,multi,multi")
3904    (set_attr "unit" "*,i387,i387,i387")
3905    (set_attr "mode" "SF")])
3907 (define_insn "truncxfsf2_i387_noop"
3908   [(set (match_operand:SF 0 "register_operand" "=f")
3909         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3910   "TARGET_80387 && flag_unsafe_math_optimizations"
3912   return output_387_reg_move (insn, operands);
3914   [(set_attr "type" "fmov")
3915    (set_attr "mode" "SF")])
3917 (define_insn "*truncxfsf2_i387"
3918   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3919         (float_truncate:SF
3920          (match_operand:XF 1 "register_operand" "f,f,f")))
3921    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3922   "TARGET_80387"
3924   gcc_assert (!which_alternative);
3925   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3926     return "fstp%z0\t%y0";
3927    else
3928      return "fst%z0\t%y0";
3930   [(set_attr "type" "fmov,multi,multi")
3931    (set_attr "unit" "*,i387,i387")
3932    (set_attr "mode" "SF")])
3934 (define_insn "*truncxfsf2_i387_1"
3935   [(set (match_operand:SF 0 "memory_operand" "=m")
3936         (float_truncate:SF
3937          (match_operand:XF 1 "register_operand" "f")))]
3938   "TARGET_80387"
3940   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3941     return "fstp%z0\t%y0";
3942   else
3943     return "fst%z0\t%y0";
3945   [(set_attr "type" "fmov")
3946    (set_attr "mode" "SF")])
3948 (define_split
3949   [(set (match_operand:SF 0 "register_operand" "")
3950         (float_truncate:SF
3951          (match_operand:XF 1 "register_operand" "")))
3952    (clobber (match_operand:SF 2 "memory_operand" ""))]
3953   "TARGET_80387 && reload_completed"
3954   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3955    (set (match_dup 0) (match_dup 2))]
3956   "")
3958 (define_split
3959   [(set (match_operand:SF 0 "memory_operand" "")
3960         (float_truncate:SF
3961          (match_operand:XF 1 "register_operand" "")))
3962    (clobber (match_operand:SF 2 "memory_operand" ""))]
3963   "TARGET_80387"
3964   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3965   "")
3967 ;; Conversion from XFmode to DFmode.
3969 (define_expand "truncxfdf2"
3970   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3971                    (float_truncate:DF
3972                     (match_operand:XF 1 "register_operand" "")))
3973               (clobber (match_dup 2))])]
3974   "TARGET_80387"
3976   if (flag_unsafe_math_optimizations)
3977     {
3978       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3979       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3980       if (reg != operands[0])
3981         emit_move_insn (operands[0], reg);
3982       DONE;
3983     }
3984   else
3985     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3988 (define_insn "*truncxfdf2_mixed"
3989   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3990         (float_truncate:DF
3991          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3992    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3993   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3995   gcc_assert (!which_alternative);
3996   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3997     return "fstp%z0\t%y0";
3998   else
3999     return "fst%z0\t%y0";
4001   [(set_attr "type" "fmov,multi,multi,multi")
4002    (set_attr "unit" "*,i387,i387,i387")
4003    (set_attr "mode" "DF")])
4005 (define_insn "truncxfdf2_i387_noop"
4006   [(set (match_operand:DF 0 "register_operand" "=f")
4007         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4008   "TARGET_80387 && flag_unsafe_math_optimizations"
4010   return output_387_reg_move (insn, operands);
4012   [(set_attr "type" "fmov")
4013    (set_attr "mode" "DF")])
4015 (define_insn "*truncxfdf2_i387"
4016   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4017         (float_truncate:DF
4018          (match_operand:XF 1 "register_operand" "f,f,f")))
4019    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4020   "TARGET_80387"
4022   gcc_assert (!which_alternative);
4023   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4024     return "fstp%z0\t%y0";
4025   else
4026     return "fst%z0\t%y0";
4028   [(set_attr "type" "fmov,multi,multi")
4029    (set_attr "unit" "*,i387,i387")
4030    (set_attr "mode" "DF")])
4032 (define_insn "*truncxfdf2_i387_1"
4033   [(set (match_operand:DF 0 "memory_operand" "=m")
4034         (float_truncate:DF
4035           (match_operand:XF 1 "register_operand" "f")))]
4036   "TARGET_80387"
4038   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4039     return "fstp%z0\t%y0";
4040   else
4041     return "fst%z0\t%y0";
4043   [(set_attr "type" "fmov")
4044    (set_attr "mode" "DF")])
4046 (define_split
4047   [(set (match_operand:DF 0 "register_operand" "")
4048         (float_truncate:DF
4049          (match_operand:XF 1 "register_operand" "")))
4050    (clobber (match_operand:DF 2 "memory_operand" ""))]
4051   "TARGET_80387 && reload_completed"
4052   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4053    (set (match_dup 0) (match_dup 2))]
4054   "")
4056 (define_split
4057   [(set (match_operand:DF 0 "memory_operand" "")
4058         (float_truncate:DF
4059          (match_operand:XF 1 "register_operand" "")))
4060    (clobber (match_operand:DF 2 "memory_operand" ""))]
4061   "TARGET_80387"
4062   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4063   "")
4065 ;; Signed conversion to DImode.
4067 (define_expand "fix_truncxfdi2"
4068   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4069                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4070               (clobber (reg:CC FLAGS_REG))])]
4071   "TARGET_80387"
4073   if (TARGET_FISTTP)
4074    {
4075      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4076      DONE;
4077    }
4080 (define_expand "fix_trunc<mode>di2"
4081   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4082                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4083               (clobber (reg:CC FLAGS_REG))])]
4084   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4086   if (TARGET_FISTTP
4087       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4088    {
4089      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4090      DONE;
4091    }
4092   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4093    {
4094      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4095      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4096      if (out != operands[0])
4097         emit_move_insn (operands[0], out);
4098      DONE;
4099    }
4102 ;; Signed conversion to SImode.
4104 (define_expand "fix_truncxfsi2"
4105   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4106                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4107               (clobber (reg:CC FLAGS_REG))])]
4108   "TARGET_80387"
4110   if (TARGET_FISTTP)
4111    {
4112      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4113      DONE;
4114    }
4117 (define_expand "fix_trunc<mode>si2"
4118   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4119                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4120               (clobber (reg:CC FLAGS_REG))])]
4121   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4123   if (TARGET_FISTTP
4124       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4125    {
4126      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4127      DONE;
4128    }
4129   if (SSE_FLOAT_MODE_P (<MODE>mode))
4130    {
4131      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4132      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4133      if (out != operands[0])
4134         emit_move_insn (operands[0], out);
4135      DONE;
4136    }
4139 ;; Signed conversion to HImode.
4141 (define_expand "fix_trunc<mode>hi2"
4142   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4143                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4144               (clobber (reg:CC FLAGS_REG))])]
4145   "TARGET_80387
4146    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4148   if (TARGET_FISTTP)
4149    {
4150      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4151      DONE;
4152    }
4155 ;; When SSE is available, it is always faster to use it!
4156 (define_insn "fix_truncsfdi_sse"
4157   [(set (match_operand:DI 0 "register_operand" "=r,r")
4158         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4159   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4160   "cvttss2si{q}\t{%1, %0|%0, %1}"
4161   [(set_attr "type" "sseicvt")
4162    (set_attr "mode" "SF")
4163    (set_attr "athlon_decode" "double,vector")])
4165 (define_insn "fix_truncdfdi_sse"
4166   [(set (match_operand:DI 0 "register_operand" "=r,r")
4167         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4168   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4169   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4170   [(set_attr "type" "sseicvt")
4171    (set_attr "mode" "DF")
4172    (set_attr "athlon_decode" "double,vector")])
4174 (define_insn "fix_truncsfsi_sse"
4175   [(set (match_operand:SI 0 "register_operand" "=r,r")
4176         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4177   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4178   "cvttss2si\t{%1, %0|%0, %1}"
4179   [(set_attr "type" "sseicvt")
4180    (set_attr "mode" "DF")
4181    (set_attr "athlon_decode" "double,vector")])
4183 (define_insn "fix_truncdfsi_sse"
4184   [(set (match_operand:SI 0 "register_operand" "=r,r")
4185         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4186   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4187   "cvttsd2si\t{%1, %0|%0, %1}"
4188   [(set_attr "type" "sseicvt")
4189    (set_attr "mode" "DF")
4190    (set_attr "athlon_decode" "double,vector")])
4192 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4193 (define_peephole2
4194   [(set (match_operand:DF 0 "register_operand" "")
4195         (match_operand:DF 1 "memory_operand" ""))
4196    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4197         (fix:SSEMODEI24 (match_dup 0)))]
4198   "!TARGET_K8
4199    && peep2_reg_dead_p (2, operands[0])"
4200   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4201   "")
4203 (define_peephole2
4204   [(set (match_operand:SF 0 "register_operand" "")
4205         (match_operand:SF 1 "memory_operand" ""))
4206    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4207         (fix:SSEMODEI24 (match_dup 0)))]
4208   "!TARGET_K8
4209    && peep2_reg_dead_p (2, operands[0])"
4210   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4211   "")
4213 ;; Avoid vector decoded forms of the instruction.
4214 (define_peephole2
4215   [(match_scratch:DF 2 "Y")
4216    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4217         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4218   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4219   [(set (match_dup 2) (match_dup 1))
4220    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4221   "")
4223 (define_peephole2
4224   [(match_scratch:SF 2 "x")
4225    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4226         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4227   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4228   [(set (match_dup 2) (match_dup 1))
4229    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4230   "")
4232 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4233   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4234         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4235   "TARGET_FISTTP
4236    && FLOAT_MODE_P (GET_MODE (operands[1]))
4237    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4238          && (TARGET_64BIT || <MODE>mode != DImode))
4239         && TARGET_SSE_MATH)
4240    && !(reload_completed || reload_in_progress)"
4241   "#"
4242   "&& 1"
4243   [(const_int 0)]
4245   if (memory_operand (operands[0], VOIDmode))
4246     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4247   else
4248     {
4249       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4250       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4251                                                             operands[1],
4252                                                             operands[2]));
4253     }
4254   DONE;
4256   [(set_attr "type" "fisttp")
4257    (set_attr "mode" "<MODE>")])
4259 (define_insn "fix_trunc<mode>_i387_fisttp"
4260   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4261         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4262    (clobber (match_scratch:XF 2 "=&1f"))]
4263   "TARGET_FISTTP
4264    && FLOAT_MODE_P (GET_MODE (operands[1]))
4265    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4266          && (TARGET_64BIT || <MODE>mode != DImode))
4267         && TARGET_SSE_MATH)"
4268   "* return output_fix_trunc (insn, operands, 1);"
4269   [(set_attr "type" "fisttp")
4270    (set_attr "mode" "<MODE>")])
4272 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4273   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4274         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4275    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4276    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4277   "TARGET_FISTTP
4278    && FLOAT_MODE_P (GET_MODE (operands[1]))
4279    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4280         && (TARGET_64BIT || <MODE>mode != DImode))
4281         && TARGET_SSE_MATH)"
4282   "#"
4283   [(set_attr "type" "fisttp")
4284    (set_attr "mode" "<MODE>")])
4286 (define_split
4287   [(set (match_operand:X87MODEI 0 "register_operand" "")
4288         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4289    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4290    (clobber (match_scratch 3 ""))]
4291   "reload_completed"
4292   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4293               (clobber (match_dup 3))])
4294    (set (match_dup 0) (match_dup 2))]
4295   "")
4297 (define_split
4298   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4299         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4300    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4301    (clobber (match_scratch 3 ""))]
4302   "reload_completed"
4303   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4304               (clobber (match_dup 3))])]
4305   "")
4307 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4308 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4309 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4310 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4311 ;; function in i386.c.
4312 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4313   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4314         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4315    (clobber (reg:CC FLAGS_REG))]
4316   "TARGET_80387 && !TARGET_FISTTP
4317    && FLOAT_MODE_P (GET_MODE (operands[1]))
4318    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4319          && (TARGET_64BIT || <MODE>mode != DImode))
4320    && !(reload_completed || reload_in_progress)"
4321   "#"
4322   "&& 1"
4323   [(const_int 0)]
4325   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4327   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4328   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4329   if (memory_operand (operands[0], VOIDmode))
4330     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4331                                          operands[2], operands[3]));
4332   else
4333     {
4334       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4335       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4336                                                      operands[2], operands[3],
4337                                                      operands[4]));
4338     }
4339   DONE;
4341   [(set_attr "type" "fistp")
4342    (set_attr "i387_cw" "trunc")
4343    (set_attr "mode" "<MODE>")])
4345 (define_insn "fix_truncdi_i387"
4346   [(set (match_operand:DI 0 "memory_operand" "=m")
4347         (fix:DI (match_operand 1 "register_operand" "f")))
4348    (use (match_operand:HI 2 "memory_operand" "m"))
4349    (use (match_operand:HI 3 "memory_operand" "m"))
4350    (clobber (match_scratch:XF 4 "=&1f"))]
4351   "TARGET_80387 && !TARGET_FISTTP
4352    && FLOAT_MODE_P (GET_MODE (operands[1]))
4353    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4354   "* return output_fix_trunc (insn, operands, 0);"
4355   [(set_attr "type" "fistp")
4356    (set_attr "i387_cw" "trunc")
4357    (set_attr "mode" "DI")])
4359 (define_insn "fix_truncdi_i387_with_temp"
4360   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4361         (fix:DI (match_operand 1 "register_operand" "f,f")))
4362    (use (match_operand:HI 2 "memory_operand" "m,m"))
4363    (use (match_operand:HI 3 "memory_operand" "m,m"))
4364    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4365    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4366   "TARGET_80387 && !TARGET_FISTTP
4367    && FLOAT_MODE_P (GET_MODE (operands[1]))
4368    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4369   "#"
4370   [(set_attr "type" "fistp")
4371    (set_attr "i387_cw" "trunc")
4372    (set_attr "mode" "DI")])
4374 (define_split
4375   [(set (match_operand:DI 0 "register_operand" "")
4376         (fix:DI (match_operand 1 "register_operand" "")))
4377    (use (match_operand:HI 2 "memory_operand" ""))
4378    (use (match_operand:HI 3 "memory_operand" ""))
4379    (clobber (match_operand:DI 4 "memory_operand" ""))
4380    (clobber (match_scratch 5 ""))]
4381   "reload_completed"
4382   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4383               (use (match_dup 2))
4384               (use (match_dup 3))
4385               (clobber (match_dup 5))])
4386    (set (match_dup 0) (match_dup 4))]
4387   "")
4389 (define_split
4390   [(set (match_operand:DI 0 "memory_operand" "")
4391         (fix:DI (match_operand 1 "register_operand" "")))
4392    (use (match_operand:HI 2 "memory_operand" ""))
4393    (use (match_operand:HI 3 "memory_operand" ""))
4394    (clobber (match_operand:DI 4 "memory_operand" ""))
4395    (clobber (match_scratch 5 ""))]
4396   "reload_completed"
4397   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4398               (use (match_dup 2))
4399               (use (match_dup 3))
4400               (clobber (match_dup 5))])]
4401   "")
4403 (define_insn "fix_trunc<mode>_i387"
4404   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4405         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4406    (use (match_operand:HI 2 "memory_operand" "m"))
4407    (use (match_operand:HI 3 "memory_operand" "m"))]
4408   "TARGET_80387 && !TARGET_FISTTP
4409    && FLOAT_MODE_P (GET_MODE (operands[1]))
4410    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4411   "* return output_fix_trunc (insn, operands, 0);"
4412   [(set_attr "type" "fistp")
4413    (set_attr "i387_cw" "trunc")
4414    (set_attr "mode" "<MODE>")])
4416 (define_insn "fix_trunc<mode>_i387_with_temp"
4417   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4418         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4419    (use (match_operand:HI 2 "memory_operand" "m,m"))
4420    (use (match_operand:HI 3 "memory_operand" "m,m"))
4421    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4422   "TARGET_80387 && !TARGET_FISTTP
4423    && FLOAT_MODE_P (GET_MODE (operands[1]))
4424    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4425   "#"
4426   [(set_attr "type" "fistp")
4427    (set_attr "i387_cw" "trunc")
4428    (set_attr "mode" "<MODE>")])
4430 (define_split
4431   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4432         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4433    (use (match_operand:HI 2 "memory_operand" ""))
4434    (use (match_operand:HI 3 "memory_operand" ""))
4435    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4436   "reload_completed"
4437   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4438               (use (match_dup 2))
4439               (use (match_dup 3))])
4440    (set (match_dup 0) (match_dup 4))]
4441   "")
4443 (define_split
4444   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4445         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4446    (use (match_operand:HI 2 "memory_operand" ""))
4447    (use (match_operand:HI 3 "memory_operand" ""))
4448    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4449   "reload_completed"
4450   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4451               (use (match_dup 2))
4452               (use (match_dup 3))])]
4453   "")
4455 (define_insn "x86_fnstcw_1"
4456   [(set (match_operand:HI 0 "memory_operand" "=m")
4457         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4458   "TARGET_80387"
4459   "fnstcw\t%0"
4460   [(set_attr "length" "2")
4461    (set_attr "mode" "HI")
4462    (set_attr "unit" "i387")])
4464 (define_insn "x86_fldcw_1"
4465   [(set (reg:HI FPCR_REG)
4466         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4467   "TARGET_80387"
4468   "fldcw\t%0"
4469   [(set_attr "length" "2")
4470    (set_attr "mode" "HI")
4471    (set_attr "unit" "i387")
4472    (set_attr "athlon_decode" "vector")])
4474 ;; Conversion between fixed point and floating point.
4476 ;; Even though we only accept memory inputs, the backend _really_
4477 ;; wants to be able to do this between registers.
4479 (define_expand "floathisf2"
4480   [(set (match_operand:SF 0 "register_operand" "")
4481         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4482   "TARGET_80387 || TARGET_SSE_MATH"
4484   if (TARGET_SSE_MATH)
4485     {
4486       emit_insn (gen_floatsisf2 (operands[0],
4487                                  convert_to_mode (SImode, operands[1], 0)));
4488       DONE;
4489     }
4492 (define_insn "*floathisf2_i387"
4493   [(set (match_operand:SF 0 "register_operand" "=f,f")
4494         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4495   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4496   "@
4497    fild%z1\t%1
4498    #"
4499   [(set_attr "type" "fmov,multi")
4500    (set_attr "mode" "SF")
4501    (set_attr "unit" "*,i387")
4502    (set_attr "fp_int_src" "true")])
4504 (define_expand "floatsisf2"
4505   [(set (match_operand:SF 0 "register_operand" "")
4506         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4507   "TARGET_80387 || TARGET_SSE_MATH"
4508   "")
4510 (define_insn "*floatsisf2_mixed"
4511   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4512         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4513   "TARGET_MIX_SSE_I387"
4514   "@
4515    fild%z1\t%1
4516    #
4517    cvtsi2ss\t{%1, %0|%0, %1}
4518    cvtsi2ss\t{%1, %0|%0, %1}"
4519   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4520    (set_attr "mode" "SF")
4521    (set_attr "unit" "*,i387,*,*")
4522    (set_attr "athlon_decode" "*,*,vector,double")
4523    (set_attr "fp_int_src" "true")])
4525 (define_insn "*floatsisf2_sse"
4526   [(set (match_operand:SF 0 "register_operand" "=x,x")
4527         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4528   "TARGET_SSE_MATH"
4529   "cvtsi2ss\t{%1, %0|%0, %1}"
4530   [(set_attr "type" "sseicvt")
4531    (set_attr "mode" "SF")
4532    (set_attr "athlon_decode" "vector,double")
4533    (set_attr "fp_int_src" "true")])
4535 (define_insn "*floatsisf2_i387"
4536   [(set (match_operand:SF 0 "register_operand" "=f,f")
4537         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4538   "TARGET_80387"
4539   "@
4540    fild%z1\t%1
4541    #"
4542   [(set_attr "type" "fmov,multi")
4543    (set_attr "mode" "SF")
4544    (set_attr "unit" "*,i387")
4545    (set_attr "fp_int_src" "true")])
4547 (define_expand "floatdisf2"
4548   [(set (match_operand:SF 0 "register_operand" "")
4549         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4550   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4551   "")
4553 (define_insn "*floatdisf2_mixed"
4554   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4555         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4556   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4557   "@
4558    fild%z1\t%1
4559    #
4560    cvtsi2ss{q}\t{%1, %0|%0, %1}
4561    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4562   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4563    (set_attr "mode" "SF")
4564    (set_attr "unit" "*,i387,*,*")
4565    (set_attr "athlon_decode" "*,*,vector,double")
4566    (set_attr "fp_int_src" "true")])
4568 (define_insn "*floatdisf2_sse"
4569   [(set (match_operand:SF 0 "register_operand" "=x,x")
4570         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4571   "TARGET_64BIT && TARGET_SSE_MATH"
4572   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4573   [(set_attr "type" "sseicvt")
4574    (set_attr "mode" "SF")
4575    (set_attr "athlon_decode" "vector,double")
4576    (set_attr "fp_int_src" "true")])
4578 (define_insn "*floatdisf2_i387"
4579   [(set (match_operand:SF 0 "register_operand" "=f,f")
4580         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4581   "TARGET_80387"
4582   "@
4583    fild%z1\t%1
4584    #"
4585   [(set_attr "type" "fmov,multi")
4586    (set_attr "mode" "SF")
4587    (set_attr "unit" "*,i387")
4588    (set_attr "fp_int_src" "true")])
4590 (define_expand "floathidf2"
4591   [(set (match_operand:DF 0 "register_operand" "")
4592         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4593   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4595   if (TARGET_SSE2 && TARGET_SSE_MATH)
4596     {
4597       emit_insn (gen_floatsidf2 (operands[0],
4598                                  convert_to_mode (SImode, operands[1], 0)));
4599       DONE;
4600     }
4603 (define_insn "*floathidf2_i387"
4604   [(set (match_operand:DF 0 "register_operand" "=f,f")
4605         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4606   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4607   "@
4608    fild%z1\t%1
4609    #"
4610   [(set_attr "type" "fmov,multi")
4611    (set_attr "mode" "DF")
4612    (set_attr "unit" "*,i387")
4613    (set_attr "fp_int_src" "true")])
4615 (define_expand "floatsidf2"
4616   [(set (match_operand:DF 0 "register_operand" "")
4617         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4618   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4619   "")
4621 (define_insn "*floatsidf2_mixed"
4622   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4623         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4624   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4625   "@
4626    fild%z1\t%1
4627    #
4628    cvtsi2sd\t{%1, %0|%0, %1}
4629    cvtsi2sd\t{%1, %0|%0, %1}"
4630   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4631    (set_attr "mode" "DF")
4632    (set_attr "unit" "*,i387,*,*")
4633    (set_attr "athlon_decode" "*,*,double,direct")
4634    (set_attr "fp_int_src" "true")])
4636 (define_insn "*floatsidf2_sse"
4637   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4638         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4639   "TARGET_SSE2 && TARGET_SSE_MATH"
4640   "cvtsi2sd\t{%1, %0|%0, %1}"
4641   [(set_attr "type" "sseicvt")
4642    (set_attr "mode" "DF")
4643    (set_attr "athlon_decode" "double,direct")
4644    (set_attr "fp_int_src" "true")])
4646 (define_insn "*floatsidf2_i387"
4647   [(set (match_operand:DF 0 "register_operand" "=f,f")
4648         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4649   "TARGET_80387"
4650   "@
4651    fild%z1\t%1
4652    #"
4653   [(set_attr "type" "fmov,multi")
4654    (set_attr "mode" "DF")
4655    (set_attr "unit" "*,i387")
4656    (set_attr "fp_int_src" "true")])
4658 (define_expand "floatdidf2"
4659   [(set (match_operand:DF 0 "register_operand" "")
4660         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4661   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4662   "")
4664 (define_insn "*floatdidf2_mixed"
4665   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4666         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4667   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4668   "@
4669    fild%z1\t%1
4670    #
4671    cvtsi2sd{q}\t{%1, %0|%0, %1}
4672    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4673   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4674    (set_attr "mode" "DF")
4675    (set_attr "unit" "*,i387,*,*")
4676    (set_attr "athlon_decode" "*,*,double,direct")
4677    (set_attr "fp_int_src" "true")])
4679 (define_insn "*floatdidf2_sse"
4680   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4681         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4682   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4683   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4684   [(set_attr "type" "sseicvt")
4685    (set_attr "mode" "DF")
4686    (set_attr "athlon_decode" "double,direct")
4687    (set_attr "fp_int_src" "true")])
4689 (define_insn "*floatdidf2_i387"
4690   [(set (match_operand:DF 0 "register_operand" "=f,f")
4691         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4692   "TARGET_80387"
4693   "@
4694    fild%z1\t%1
4695    #"
4696   [(set_attr "type" "fmov,multi")
4697    (set_attr "mode" "DF")
4698    (set_attr "unit" "*,i387")
4699    (set_attr "fp_int_src" "true")])
4701 (define_insn "floathixf2"
4702   [(set (match_operand:XF 0 "register_operand" "=f,f")
4703         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4704   "TARGET_80387"
4705   "@
4706    fild%z1\t%1
4707    #"
4708   [(set_attr "type" "fmov,multi")
4709    (set_attr "mode" "XF")
4710    (set_attr "unit" "*,i387")
4711    (set_attr "fp_int_src" "true")])
4713 (define_insn "floatsixf2"
4714   [(set (match_operand:XF 0 "register_operand" "=f,f")
4715         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4716   "TARGET_80387"
4717   "@
4718    fild%z1\t%1
4719    #"
4720   [(set_attr "type" "fmov,multi")
4721    (set_attr "mode" "XF")
4722    (set_attr "unit" "*,i387")
4723    (set_attr "fp_int_src" "true")])
4725 (define_insn "floatdixf2"
4726   [(set (match_operand:XF 0 "register_operand" "=f,f")
4727         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4728   "TARGET_80387"
4729   "@
4730    fild%z1\t%1
4731    #"
4732   [(set_attr "type" "fmov,multi")
4733    (set_attr "mode" "XF")
4734    (set_attr "unit" "*,i387")
4735    (set_attr "fp_int_src" "true")])
4737 ;; %%% Kill these when reload knows how to do it.
4738 (define_split
4739   [(set (match_operand 0 "fp_register_operand" "")
4740         (float (match_operand 1 "register_operand" "")))]
4741   "reload_completed
4742    && TARGET_80387
4743    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4744   [(const_int 0)]
4746   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4747   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4748   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4749   ix86_free_from_memory (GET_MODE (operands[1]));
4750   DONE;
4753 (define_expand "floatunssisf2"
4754   [(use (match_operand:SF 0 "register_operand" ""))
4755    (use (match_operand:SI 1 "register_operand" ""))]
4756   "!TARGET_64BIT && TARGET_SSE_MATH"
4757   "x86_emit_floatuns (operands); DONE;")
4759 (define_expand "floatunsdisf2"
4760   [(use (match_operand:SF 0 "register_operand" ""))
4761    (use (match_operand:DI 1 "register_operand" ""))]
4762   "TARGET_64BIT && TARGET_SSE_MATH"
4763   "x86_emit_floatuns (operands); DONE;")
4765 (define_expand "floatunsdidf2"
4766   [(use (match_operand:DF 0 "register_operand" ""))
4767    (use (match_operand:DI 1 "register_operand" ""))]
4768   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4769   "x86_emit_floatuns (operands); DONE;")
4771 ;; SSE extract/set expanders
4774 ;; Add instructions
4776 ;; %%% splits for addditi3
4778 (define_expand "addti3"
4779   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4780         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4781                  (match_operand:TI 2 "x86_64_general_operand" "")))
4782    (clobber (reg:CC FLAGS_REG))]
4783   "TARGET_64BIT"
4784   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4786 (define_insn "*addti3_1"
4787   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4788         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4789                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4790    (clobber (reg:CC FLAGS_REG))]
4791   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4792   "#")
4794 (define_split
4795   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4796         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4797                  (match_operand:TI 2 "general_operand" "")))
4798    (clobber (reg:CC FLAGS_REG))]
4799   "TARGET_64BIT && reload_completed"
4800   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4801                                           UNSPEC_ADD_CARRY))
4802               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4803    (parallel [(set (match_dup 3)
4804                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4805                                      (match_dup 4))
4806                             (match_dup 5)))
4807               (clobber (reg:CC FLAGS_REG))])]
4808   "split_ti (operands+0, 1, operands+0, operands+3);
4809    split_ti (operands+1, 1, operands+1, operands+4);
4810    split_ti (operands+2, 1, operands+2, operands+5);")
4812 ;; %%% splits for addsidi3
4813 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4814 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4815 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4817 (define_expand "adddi3"
4818   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4819         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4820                  (match_operand:DI 2 "x86_64_general_operand" "")))
4821    (clobber (reg:CC FLAGS_REG))]
4822   ""
4823   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4825 (define_insn "*adddi3_1"
4826   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4827         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4828                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4829    (clobber (reg:CC FLAGS_REG))]
4830   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4831   "#")
4833 (define_split
4834   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4835         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4836                  (match_operand:DI 2 "general_operand" "")))
4837    (clobber (reg:CC FLAGS_REG))]
4838   "!TARGET_64BIT && reload_completed"
4839   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4840                                           UNSPEC_ADD_CARRY))
4841               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4842    (parallel [(set (match_dup 3)
4843                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4844                                      (match_dup 4))
4845                             (match_dup 5)))
4846               (clobber (reg:CC FLAGS_REG))])]
4847   "split_di (operands+0, 1, operands+0, operands+3);
4848    split_di (operands+1, 1, operands+1, operands+4);
4849    split_di (operands+2, 1, operands+2, operands+5);")
4851 (define_insn "adddi3_carry_rex64"
4852   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4853           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4854                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4855                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4856    (clobber (reg:CC FLAGS_REG))]
4857   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4858   "adc{q}\t{%2, %0|%0, %2}"
4859   [(set_attr "type" "alu")
4860    (set_attr "pent_pair" "pu")
4861    (set_attr "mode" "DI")])
4863 (define_insn "*adddi3_cc_rex64"
4864   [(set (reg:CC FLAGS_REG)
4865         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4866                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4867                    UNSPEC_ADD_CARRY))
4868    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4869         (plus:DI (match_dup 1) (match_dup 2)))]
4870   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4871   "add{q}\t{%2, %0|%0, %2}"
4872   [(set_attr "type" "alu")
4873    (set_attr "mode" "DI")])
4875 (define_insn "addqi3_carry"
4876   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4877           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4878                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4879                    (match_operand:QI 2 "general_operand" "qi,qm")))
4880    (clobber (reg:CC FLAGS_REG))]
4881   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4882   "adc{b}\t{%2, %0|%0, %2}"
4883   [(set_attr "type" "alu")
4884    (set_attr "pent_pair" "pu")
4885    (set_attr "mode" "QI")])
4887 (define_insn "addhi3_carry"
4888   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4889           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4890                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4891                    (match_operand:HI 2 "general_operand" "ri,rm")))
4892    (clobber (reg:CC FLAGS_REG))]
4893   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4894   "adc{w}\t{%2, %0|%0, %2}"
4895   [(set_attr "type" "alu")
4896    (set_attr "pent_pair" "pu")
4897    (set_attr "mode" "HI")])
4899 (define_insn "addsi3_carry"
4900   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4901           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4902                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4903                    (match_operand:SI 2 "general_operand" "ri,rm")))
4904    (clobber (reg:CC FLAGS_REG))]
4905   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4906   "adc{l}\t{%2, %0|%0, %2}"
4907   [(set_attr "type" "alu")
4908    (set_attr "pent_pair" "pu")
4909    (set_attr "mode" "SI")])
4911 (define_insn "*addsi3_carry_zext"
4912   [(set (match_operand:DI 0 "register_operand" "=r")
4913           (zero_extend:DI
4914             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4915                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4916                      (match_operand:SI 2 "general_operand" "rim"))))
4917    (clobber (reg:CC FLAGS_REG))]
4918   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4919   "adc{l}\t{%2, %k0|%k0, %2}"
4920   [(set_attr "type" "alu")
4921    (set_attr "pent_pair" "pu")
4922    (set_attr "mode" "SI")])
4924 (define_insn "*addsi3_cc"
4925   [(set (reg:CC FLAGS_REG)
4926         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4927                     (match_operand:SI 2 "general_operand" "ri,rm")]
4928                    UNSPEC_ADD_CARRY))
4929    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4930         (plus:SI (match_dup 1) (match_dup 2)))]
4931   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4932   "add{l}\t{%2, %0|%0, %2}"
4933   [(set_attr "type" "alu")
4934    (set_attr "mode" "SI")])
4936 (define_insn "addqi3_cc"
4937   [(set (reg:CC FLAGS_REG)
4938         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4939                     (match_operand:QI 2 "general_operand" "qi,qm")]
4940                    UNSPEC_ADD_CARRY))
4941    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4942         (plus:QI (match_dup 1) (match_dup 2)))]
4943   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4944   "add{b}\t{%2, %0|%0, %2}"
4945   [(set_attr "type" "alu")
4946    (set_attr "mode" "QI")])
4948 (define_expand "addsi3"
4949   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4950                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4951                             (match_operand:SI 2 "general_operand" "")))
4952               (clobber (reg:CC FLAGS_REG))])]
4953   ""
4954   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4956 (define_insn "*lea_1"
4957   [(set (match_operand:SI 0 "register_operand" "=r")
4958         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4959   "!TARGET_64BIT"
4960   "lea{l}\t{%a1, %0|%0, %a1}"
4961   [(set_attr "type" "lea")
4962    (set_attr "mode" "SI")])
4964 (define_insn "*lea_1_rex64"
4965   [(set (match_operand:SI 0 "register_operand" "=r")
4966         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4967   "TARGET_64BIT"
4968   "lea{l}\t{%a1, %0|%0, %a1}"
4969   [(set_attr "type" "lea")
4970    (set_attr "mode" "SI")])
4972 (define_insn "*lea_1_zext"
4973   [(set (match_operand:DI 0 "register_operand" "=r")
4974         (zero_extend:DI
4975          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4976   "TARGET_64BIT"
4977   "lea{l}\t{%a1, %k0|%k0, %a1}"
4978   [(set_attr "type" "lea")
4979    (set_attr "mode" "SI")])
4981 (define_insn "*lea_2_rex64"
4982   [(set (match_operand:DI 0 "register_operand" "=r")
4983         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4984   "TARGET_64BIT"
4985   "lea{q}\t{%a1, %0|%0, %a1}"
4986   [(set_attr "type" "lea")
4987    (set_attr "mode" "DI")])
4989 ;; The lea patterns for non-Pmodes needs to be matched by several
4990 ;; insns converted to real lea by splitters.
4992 (define_insn_and_split "*lea_general_1"
4993   [(set (match_operand 0 "register_operand" "=r")
4994         (plus (plus (match_operand 1 "index_register_operand" "l")
4995                     (match_operand 2 "register_operand" "r"))
4996               (match_operand 3 "immediate_operand" "i")))]
4997   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4998     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4999    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5000    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5001    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5002    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5003        || GET_MODE (operands[3]) == VOIDmode)"
5004   "#"
5005   "&& reload_completed"
5006   [(const_int 0)]
5008   rtx pat;
5009   operands[0] = gen_lowpart (SImode, operands[0]);
5010   operands[1] = gen_lowpart (Pmode, operands[1]);
5011   operands[2] = gen_lowpart (Pmode, operands[2]);
5012   operands[3] = gen_lowpart (Pmode, operands[3]);
5013   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5014                       operands[3]);
5015   if (Pmode != SImode)
5016     pat = gen_rtx_SUBREG (SImode, pat, 0);
5017   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5018   DONE;
5020   [(set_attr "type" "lea")
5021    (set_attr "mode" "SI")])
5023 (define_insn_and_split "*lea_general_1_zext"
5024   [(set (match_operand:DI 0 "register_operand" "=r")
5025         (zero_extend:DI
5026           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5027                             (match_operand:SI 2 "register_operand" "r"))
5028                    (match_operand:SI 3 "immediate_operand" "i"))))]
5029   "TARGET_64BIT"
5030   "#"
5031   "&& reload_completed"
5032   [(set (match_dup 0)
5033         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5034                                                      (match_dup 2))
5035                                             (match_dup 3)) 0)))]
5037   operands[1] = gen_lowpart (Pmode, operands[1]);
5038   operands[2] = gen_lowpart (Pmode, operands[2]);
5039   operands[3] = gen_lowpart (Pmode, operands[3]);
5041   [(set_attr "type" "lea")
5042    (set_attr "mode" "SI")])
5044 (define_insn_and_split "*lea_general_2"
5045   [(set (match_operand 0 "register_operand" "=r")
5046         (plus (mult (match_operand 1 "index_register_operand" "l")
5047                     (match_operand 2 "const248_operand" "i"))
5048               (match_operand 3 "nonmemory_operand" "ri")))]
5049   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5050     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5051    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5052    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5053    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5054        || GET_MODE (operands[3]) == VOIDmode)"
5055   "#"
5056   "&& reload_completed"
5057   [(const_int 0)]
5059   rtx pat;
5060   operands[0] = gen_lowpart (SImode, operands[0]);
5061   operands[1] = gen_lowpart (Pmode, operands[1]);
5062   operands[3] = gen_lowpart (Pmode, operands[3]);
5063   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5064                       operands[3]);
5065   if (Pmode != SImode)
5066     pat = gen_rtx_SUBREG (SImode, pat, 0);
5067   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5068   DONE;
5070   [(set_attr "type" "lea")
5071    (set_attr "mode" "SI")])
5073 (define_insn_and_split "*lea_general_2_zext"
5074   [(set (match_operand:DI 0 "register_operand" "=r")
5075         (zero_extend:DI
5076           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5077                             (match_operand:SI 2 "const248_operand" "n"))
5078                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5079   "TARGET_64BIT"
5080   "#"
5081   "&& reload_completed"
5082   [(set (match_dup 0)
5083         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5084                                                      (match_dup 2))
5085                                             (match_dup 3)) 0)))]
5087   operands[1] = gen_lowpart (Pmode, operands[1]);
5088   operands[3] = gen_lowpart (Pmode, operands[3]);
5090   [(set_attr "type" "lea")
5091    (set_attr "mode" "SI")])
5093 (define_insn_and_split "*lea_general_3"
5094   [(set (match_operand 0 "register_operand" "=r")
5095         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5096                           (match_operand 2 "const248_operand" "i"))
5097                     (match_operand 3 "register_operand" "r"))
5098               (match_operand 4 "immediate_operand" "i")))]
5099   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5100     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5101    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5102    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5103    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5104   "#"
5105   "&& reload_completed"
5106   [(const_int 0)]
5108   rtx pat;
5109   operands[0] = gen_lowpart (SImode, operands[0]);
5110   operands[1] = gen_lowpart (Pmode, operands[1]);
5111   operands[3] = gen_lowpart (Pmode, operands[3]);
5112   operands[4] = gen_lowpart (Pmode, operands[4]);
5113   pat = gen_rtx_PLUS (Pmode,
5114                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5115                                                          operands[2]),
5116                                     operands[3]),
5117                       operands[4]);
5118   if (Pmode != SImode)
5119     pat = gen_rtx_SUBREG (SImode, pat, 0);
5120   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5121   DONE;
5123   [(set_attr "type" "lea")
5124    (set_attr "mode" "SI")])
5126 (define_insn_and_split "*lea_general_3_zext"
5127   [(set (match_operand:DI 0 "register_operand" "=r")
5128         (zero_extend:DI
5129           (plus:SI (plus:SI (mult:SI
5130                               (match_operand:SI 1 "index_register_operand" "l")
5131                               (match_operand:SI 2 "const248_operand" "n"))
5132                             (match_operand:SI 3 "register_operand" "r"))
5133                    (match_operand:SI 4 "immediate_operand" "i"))))]
5134   "TARGET_64BIT"
5135   "#"
5136   "&& reload_completed"
5137   [(set (match_dup 0)
5138         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5139                                                               (match_dup 2))
5140                                                      (match_dup 3))
5141                                             (match_dup 4)) 0)))]
5143   operands[1] = gen_lowpart (Pmode, operands[1]);
5144   operands[3] = gen_lowpart (Pmode, operands[3]);
5145   operands[4] = gen_lowpart (Pmode, operands[4]);
5147   [(set_attr "type" "lea")
5148    (set_attr "mode" "SI")])
5150 (define_insn "*adddi_1_rex64"
5151   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5152         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5153                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5154    (clobber (reg:CC FLAGS_REG))]
5155   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5157   switch (get_attr_type (insn))
5158     {
5159     case TYPE_LEA:
5160       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5161       return "lea{q}\t{%a2, %0|%0, %a2}";
5163     case TYPE_INCDEC:
5164       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5165       if (operands[2] == const1_rtx)
5166         return "inc{q}\t%0";
5167       else
5168         {
5169           gcc_assert (operands[2] == constm1_rtx);
5170           return "dec{q}\t%0";
5171         }
5173     default:
5174       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5176       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5177          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5178       if (GET_CODE (operands[2]) == CONST_INT
5179           /* Avoid overflows.  */
5180           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5181           && (INTVAL (operands[2]) == 128
5182               || (INTVAL (operands[2]) < 0
5183                   && INTVAL (operands[2]) != -128)))
5184         {
5185           operands[2] = GEN_INT (-INTVAL (operands[2]));
5186           return "sub{q}\t{%2, %0|%0, %2}";
5187         }
5188       return "add{q}\t{%2, %0|%0, %2}";
5189     }
5191   [(set (attr "type")
5192      (cond [(eq_attr "alternative" "2")
5193               (const_string "lea")
5194             ; Current assemblers are broken and do not allow @GOTOFF in
5195             ; ought but a memory context.
5196             (match_operand:DI 2 "pic_symbolic_operand" "")
5197               (const_string "lea")
5198             (match_operand:DI 2 "incdec_operand" "")
5199               (const_string "incdec")
5200            ]
5201            (const_string "alu")))
5202    (set_attr "mode" "DI")])
5204 ;; Convert lea to the lea pattern to avoid flags dependency.
5205 (define_split
5206   [(set (match_operand:DI 0 "register_operand" "")
5207         (plus:DI (match_operand:DI 1 "register_operand" "")
5208                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5209    (clobber (reg:CC FLAGS_REG))]
5210   "TARGET_64BIT && reload_completed
5211    && true_regnum (operands[0]) != true_regnum (operands[1])"
5212   [(set (match_dup 0)
5213         (plus:DI (match_dup 1)
5214                  (match_dup 2)))]
5215   "")
5217 (define_insn "*adddi_2_rex64"
5218   [(set (reg FLAGS_REG)
5219         (compare
5220           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5221                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5222           (const_int 0)))
5223    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5224         (plus:DI (match_dup 1) (match_dup 2)))]
5225   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5226    && ix86_binary_operator_ok (PLUS, DImode, operands)
5227    /* Current assemblers are broken and do not allow @GOTOFF in
5228       ought but a memory context.  */
5229    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5231   switch (get_attr_type (insn))
5232     {
5233     case TYPE_INCDEC:
5234       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5235       if (operands[2] == const1_rtx)
5236         return "inc{q}\t%0";
5237       else
5238         {
5239           gcc_assert (operands[2] == constm1_rtx);
5240           return "dec{q}\t%0";
5241         }
5243     default:
5244       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5245       /* ???? We ought to handle there the 32bit case too
5246          - do we need new constraint?  */
5247       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5248          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5249       if (GET_CODE (operands[2]) == CONST_INT
5250           /* Avoid overflows.  */
5251           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5252           && (INTVAL (operands[2]) == 128
5253               || (INTVAL (operands[2]) < 0
5254                   && INTVAL (operands[2]) != -128)))
5255         {
5256           operands[2] = GEN_INT (-INTVAL (operands[2]));
5257           return "sub{q}\t{%2, %0|%0, %2}";
5258         }
5259       return "add{q}\t{%2, %0|%0, %2}";
5260     }
5262   [(set (attr "type")
5263      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5264         (const_string "incdec")
5265         (const_string "alu")))
5266    (set_attr "mode" "DI")])
5268 (define_insn "*adddi_3_rex64"
5269   [(set (reg FLAGS_REG)
5270         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5271                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5272    (clobber (match_scratch:DI 0 "=r"))]
5273   "TARGET_64BIT
5274    && ix86_match_ccmode (insn, CCZmode)
5275    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5276    /* Current assemblers are broken and do not allow @GOTOFF in
5277       ought but a memory context.  */
5278    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5280   switch (get_attr_type (insn))
5281     {
5282     case TYPE_INCDEC:
5283       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5284       if (operands[2] == const1_rtx)
5285         return "inc{q}\t%0";
5286       else
5287         {
5288           gcc_assert (operands[2] == constm1_rtx);
5289           return "dec{q}\t%0";
5290         }
5292     default:
5293       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5294       /* ???? We ought to handle there the 32bit case too
5295          - do we need new constraint?  */
5296       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5297          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5298       if (GET_CODE (operands[2]) == CONST_INT
5299           /* Avoid overflows.  */
5300           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5301           && (INTVAL (operands[2]) == 128
5302               || (INTVAL (operands[2]) < 0
5303                   && INTVAL (operands[2]) != -128)))
5304         {
5305           operands[2] = GEN_INT (-INTVAL (operands[2]));
5306           return "sub{q}\t{%2, %0|%0, %2}";
5307         }
5308       return "add{q}\t{%2, %0|%0, %2}";
5309     }
5311   [(set (attr "type")
5312      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5313         (const_string "incdec")
5314         (const_string "alu")))
5315    (set_attr "mode" "DI")])
5317 ; For comparisons against 1, -1 and 128, we may generate better code
5318 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5319 ; is matched then.  We can't accept general immediate, because for
5320 ; case of overflows,  the result is messed up.
5321 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5322 ; when negated.
5323 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5324 ; only for comparisons not depending on it.
5325 (define_insn "*adddi_4_rex64"
5326   [(set (reg FLAGS_REG)
5327         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5328                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5329    (clobber (match_scratch:DI 0 "=rm"))]
5330   "TARGET_64BIT
5331    &&  ix86_match_ccmode (insn, CCGCmode)"
5333   switch (get_attr_type (insn))
5334     {
5335     case TYPE_INCDEC:
5336       if (operands[2] == constm1_rtx)
5337         return "inc{q}\t%0";
5338       else
5339         {
5340           gcc_assert (operands[2] == const1_rtx);
5341           return "dec{q}\t%0";
5342         }
5344     default:
5345       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5346       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5347          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5348       if ((INTVAL (operands[2]) == -128
5349            || (INTVAL (operands[2]) > 0
5350                && INTVAL (operands[2]) != 128))
5351           /* Avoid overflows.  */
5352           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5353         return "sub{q}\t{%2, %0|%0, %2}";
5354       operands[2] = GEN_INT (-INTVAL (operands[2]));
5355       return "add{q}\t{%2, %0|%0, %2}";
5356     }
5358   [(set (attr "type")
5359      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5360         (const_string "incdec")
5361         (const_string "alu")))
5362    (set_attr "mode" "DI")])
5364 (define_insn "*adddi_5_rex64"
5365   [(set (reg FLAGS_REG)
5366         (compare
5367           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5368                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5369           (const_int 0)))
5370    (clobber (match_scratch:DI 0 "=r"))]
5371   "TARGET_64BIT
5372    && ix86_match_ccmode (insn, CCGOCmode)
5373    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5374    /* Current assemblers are broken and do not allow @GOTOFF in
5375       ought but a memory context.  */
5376    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5378   switch (get_attr_type (insn))
5379     {
5380     case TYPE_INCDEC:
5381       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5382       if (operands[2] == const1_rtx)
5383         return "inc{q}\t%0";
5384       else
5385         {
5386           gcc_assert (operands[2] == constm1_rtx);
5387           return "dec{q}\t%0";
5388         }
5390     default:
5391       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5392       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5393          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5394       if (GET_CODE (operands[2]) == CONST_INT
5395           /* Avoid overflows.  */
5396           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5397           && (INTVAL (operands[2]) == 128
5398               || (INTVAL (operands[2]) < 0
5399                   && INTVAL (operands[2]) != -128)))
5400         {
5401           operands[2] = GEN_INT (-INTVAL (operands[2]));
5402           return "sub{q}\t{%2, %0|%0, %2}";
5403         }
5404       return "add{q}\t{%2, %0|%0, %2}";
5405     }
5407   [(set (attr "type")
5408      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5409         (const_string "incdec")
5410         (const_string "alu")))
5411    (set_attr "mode" "DI")])
5414 (define_insn "*addsi_1"
5415   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5416         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5417                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5418    (clobber (reg:CC FLAGS_REG))]
5419   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5421   switch (get_attr_type (insn))
5422     {
5423     case TYPE_LEA:
5424       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5425       return "lea{l}\t{%a2, %0|%0, %a2}";
5427     case TYPE_INCDEC:
5428       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5429       if (operands[2] == const1_rtx)
5430         return "inc{l}\t%0";
5431       else
5432         {
5433           gcc_assert (operands[2] == constm1_rtx);
5434           return "dec{l}\t%0";
5435         }
5437     default:
5438       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5440       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5441          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5442       if (GET_CODE (operands[2]) == CONST_INT
5443           && (INTVAL (operands[2]) == 128
5444               || (INTVAL (operands[2]) < 0
5445                   && INTVAL (operands[2]) != -128)))
5446         {
5447           operands[2] = GEN_INT (-INTVAL (operands[2]));
5448           return "sub{l}\t{%2, %0|%0, %2}";
5449         }
5450       return "add{l}\t{%2, %0|%0, %2}";
5451     }
5453   [(set (attr "type")
5454      (cond [(eq_attr "alternative" "2")
5455               (const_string "lea")
5456             ; Current assemblers are broken and do not allow @GOTOFF in
5457             ; ought but a memory context.
5458             (match_operand:SI 2 "pic_symbolic_operand" "")
5459               (const_string "lea")
5460             (match_operand:SI 2 "incdec_operand" "")
5461               (const_string "incdec")
5462            ]
5463            (const_string "alu")))
5464    (set_attr "mode" "SI")])
5466 ;; Convert lea to the lea pattern to avoid flags dependency.
5467 (define_split
5468   [(set (match_operand 0 "register_operand" "")
5469         (plus (match_operand 1 "register_operand" "")
5470               (match_operand 2 "nonmemory_operand" "")))
5471    (clobber (reg:CC FLAGS_REG))]
5472   "reload_completed
5473    && true_regnum (operands[0]) != true_regnum (operands[1])"
5474   [(const_int 0)]
5476   rtx pat;
5477   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5478      may confuse gen_lowpart.  */
5479   if (GET_MODE (operands[0]) != Pmode)
5480     {
5481       operands[1] = gen_lowpart (Pmode, operands[1]);
5482       operands[2] = gen_lowpart (Pmode, operands[2]);
5483     }
5484   operands[0] = gen_lowpart (SImode, operands[0]);
5485   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5486   if (Pmode != SImode)
5487     pat = gen_rtx_SUBREG (SImode, pat, 0);
5488   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5489   DONE;
5492 ;; It may seem that nonimmediate operand is proper one for operand 1.
5493 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5494 ;; we take care in ix86_binary_operator_ok to not allow two memory
5495 ;; operands so proper swapping will be done in reload.  This allow
5496 ;; patterns constructed from addsi_1 to match.
5497 (define_insn "addsi_1_zext"
5498   [(set (match_operand:DI 0 "register_operand" "=r,r")
5499         (zero_extend:DI
5500           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5501                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5502    (clobber (reg:CC FLAGS_REG))]
5503   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5505   switch (get_attr_type (insn))
5506     {
5507     case TYPE_LEA:
5508       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5509       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5511     case TYPE_INCDEC:
5512       if (operands[2] == const1_rtx)
5513         return "inc{l}\t%k0";
5514       else
5515         {
5516           gcc_assert (operands[2] == constm1_rtx);
5517           return "dec{l}\t%k0";
5518         }
5520     default:
5521       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5522          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5523       if (GET_CODE (operands[2]) == CONST_INT
5524           && (INTVAL (operands[2]) == 128
5525               || (INTVAL (operands[2]) < 0
5526                   && INTVAL (operands[2]) != -128)))
5527         {
5528           operands[2] = GEN_INT (-INTVAL (operands[2]));
5529           return "sub{l}\t{%2, %k0|%k0, %2}";
5530         }
5531       return "add{l}\t{%2, %k0|%k0, %2}";
5532     }
5534   [(set (attr "type")
5535      (cond [(eq_attr "alternative" "1")
5536               (const_string "lea")
5537             ; Current assemblers are broken and do not allow @GOTOFF in
5538             ; ought but a memory context.
5539             (match_operand:SI 2 "pic_symbolic_operand" "")
5540               (const_string "lea")
5541             (match_operand:SI 2 "incdec_operand" "")
5542               (const_string "incdec")
5543            ]
5544            (const_string "alu")))
5545    (set_attr "mode" "SI")])
5547 ;; Convert lea to the lea pattern to avoid flags dependency.
5548 (define_split
5549   [(set (match_operand:DI 0 "register_operand" "")
5550         (zero_extend:DI
5551           (plus:SI (match_operand:SI 1 "register_operand" "")
5552                    (match_operand:SI 2 "nonmemory_operand" ""))))
5553    (clobber (reg:CC FLAGS_REG))]
5554   "TARGET_64BIT && reload_completed
5555    && true_regnum (operands[0]) != true_regnum (operands[1])"
5556   [(set (match_dup 0)
5557         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5559   operands[1] = gen_lowpart (Pmode, operands[1]);
5560   operands[2] = gen_lowpart (Pmode, operands[2]);
5563 (define_insn "*addsi_2"
5564   [(set (reg FLAGS_REG)
5565         (compare
5566           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5567                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5568           (const_int 0)))
5569    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5570         (plus:SI (match_dup 1) (match_dup 2)))]
5571   "ix86_match_ccmode (insn, CCGOCmode)
5572    && ix86_binary_operator_ok (PLUS, SImode, operands)
5573    /* Current assemblers are broken and do not allow @GOTOFF in
5574       ought but a memory context.  */
5575    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5577   switch (get_attr_type (insn))
5578     {
5579     case TYPE_INCDEC:
5580       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5581       if (operands[2] == const1_rtx)
5582         return "inc{l}\t%0";
5583       else
5584         {
5585           gcc_assert (operands[2] == constm1_rtx);
5586           return "dec{l}\t%0";
5587         }
5589     default:
5590       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5591       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5592          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5593       if (GET_CODE (operands[2]) == CONST_INT
5594           && (INTVAL (operands[2]) == 128
5595               || (INTVAL (operands[2]) < 0
5596                   && INTVAL (operands[2]) != -128)))
5597         {
5598           operands[2] = GEN_INT (-INTVAL (operands[2]));
5599           return "sub{l}\t{%2, %0|%0, %2}";
5600         }
5601       return "add{l}\t{%2, %0|%0, %2}";
5602     }
5604   [(set (attr "type")
5605      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5606         (const_string "incdec")
5607         (const_string "alu")))
5608    (set_attr "mode" "SI")])
5610 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5611 (define_insn "*addsi_2_zext"
5612   [(set (reg FLAGS_REG)
5613         (compare
5614           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5615                    (match_operand:SI 2 "general_operand" "rmni"))
5616           (const_int 0)))
5617    (set (match_operand:DI 0 "register_operand" "=r")
5618         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5619   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5620    && ix86_binary_operator_ok (PLUS, SImode, operands)
5621    /* Current assemblers are broken and do not allow @GOTOFF in
5622       ought but a memory context.  */
5623    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5625   switch (get_attr_type (insn))
5626     {
5627     case TYPE_INCDEC:
5628       if (operands[2] == const1_rtx)
5629         return "inc{l}\t%k0";
5630       else
5631         {
5632           gcc_assert (operands[2] == constm1_rtx);
5633           return "dec{l}\t%k0";
5634         }
5636     default:
5637       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5638          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5639       if (GET_CODE (operands[2]) == CONST_INT
5640           && (INTVAL (operands[2]) == 128
5641               || (INTVAL (operands[2]) < 0
5642                   && INTVAL (operands[2]) != -128)))
5643         {
5644           operands[2] = GEN_INT (-INTVAL (operands[2]));
5645           return "sub{l}\t{%2, %k0|%k0, %2}";
5646         }
5647       return "add{l}\t{%2, %k0|%k0, %2}";
5648     }
5650   [(set (attr "type")
5651      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5652         (const_string "incdec")
5653         (const_string "alu")))
5654    (set_attr "mode" "SI")])
5656 (define_insn "*addsi_3"
5657   [(set (reg FLAGS_REG)
5658         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5659                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5660    (clobber (match_scratch:SI 0 "=r"))]
5661   "ix86_match_ccmode (insn, CCZmode)
5662    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5663    /* Current assemblers are broken and do not allow @GOTOFF in
5664       ought but a memory context.  */
5665    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5667   switch (get_attr_type (insn))
5668     {
5669     case TYPE_INCDEC:
5670       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5671       if (operands[2] == const1_rtx)
5672         return "inc{l}\t%0";
5673       else
5674         {
5675           gcc_assert (operands[2] == constm1_rtx);
5676           return "dec{l}\t%0";
5677         }
5679     default:
5680       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5682          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5683       if (GET_CODE (operands[2]) == CONST_INT
5684           && (INTVAL (operands[2]) == 128
5685               || (INTVAL (operands[2]) < 0
5686                   && INTVAL (operands[2]) != -128)))
5687         {
5688           operands[2] = GEN_INT (-INTVAL (operands[2]));
5689           return "sub{l}\t{%2, %0|%0, %2}";
5690         }
5691       return "add{l}\t{%2, %0|%0, %2}";
5692     }
5694   [(set (attr "type")
5695      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5696         (const_string "incdec")
5697         (const_string "alu")))
5698    (set_attr "mode" "SI")])
5700 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5701 (define_insn "*addsi_3_zext"
5702   [(set (reg FLAGS_REG)
5703         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5704                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5705    (set (match_operand:DI 0 "register_operand" "=r")
5706         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5707   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5708    && ix86_binary_operator_ok (PLUS, SImode, operands)
5709    /* Current assemblers are broken and do not allow @GOTOFF in
5710       ought but a memory context.  */
5711    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5713   switch (get_attr_type (insn))
5714     {
5715     case TYPE_INCDEC:
5716       if (operands[2] == const1_rtx)
5717         return "inc{l}\t%k0";
5718       else
5719         {
5720           gcc_assert (operands[2] == constm1_rtx);
5721           return "dec{l}\t%k0";
5722         }
5724     default:
5725       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5726          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5727       if (GET_CODE (operands[2]) == CONST_INT
5728           && (INTVAL (operands[2]) == 128
5729               || (INTVAL (operands[2]) < 0
5730                   && INTVAL (operands[2]) != -128)))
5731         {
5732           operands[2] = GEN_INT (-INTVAL (operands[2]));
5733           return "sub{l}\t{%2, %k0|%k0, %2}";
5734         }
5735       return "add{l}\t{%2, %k0|%k0, %2}";
5736     }
5738   [(set (attr "type")
5739      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5740         (const_string "incdec")
5741         (const_string "alu")))
5742    (set_attr "mode" "SI")])
5744 ; For comparisons against 1, -1 and 128, we may generate better code
5745 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5746 ; is matched then.  We can't accept general immediate, because for
5747 ; case of overflows,  the result is messed up.
5748 ; This pattern also don't hold of 0x80000000, since the value overflows
5749 ; when negated.
5750 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5751 ; only for comparisons not depending on it.
5752 (define_insn "*addsi_4"
5753   [(set (reg FLAGS_REG)
5754         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5755                  (match_operand:SI 2 "const_int_operand" "n")))
5756    (clobber (match_scratch:SI 0 "=rm"))]
5757   "ix86_match_ccmode (insn, CCGCmode)
5758    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5760   switch (get_attr_type (insn))
5761     {
5762     case TYPE_INCDEC:
5763       if (operands[2] == constm1_rtx)
5764         return "inc{l}\t%0";
5765       else
5766         {
5767           gcc_assert (operands[2] == const1_rtx);
5768           return "dec{l}\t%0";
5769         }
5771     default:
5772       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5773       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5774          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5775       if ((INTVAL (operands[2]) == -128
5776            || (INTVAL (operands[2]) > 0
5777                && INTVAL (operands[2]) != 128)))
5778         return "sub{l}\t{%2, %0|%0, %2}";
5779       operands[2] = GEN_INT (-INTVAL (operands[2]));
5780       return "add{l}\t{%2, %0|%0, %2}";
5781     }
5783   [(set (attr "type")
5784      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5785         (const_string "incdec")
5786         (const_string "alu")))
5787    (set_attr "mode" "SI")])
5789 (define_insn "*addsi_5"
5790   [(set (reg FLAGS_REG)
5791         (compare
5792           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5793                    (match_operand:SI 2 "general_operand" "rmni"))
5794           (const_int 0)))
5795    (clobber (match_scratch:SI 0 "=r"))]
5796   "ix86_match_ccmode (insn, CCGOCmode)
5797    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5798    /* Current assemblers are broken and do not allow @GOTOFF in
5799       ought but a memory context.  */
5800    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5802   switch (get_attr_type (insn))
5803     {
5804     case TYPE_INCDEC:
5805       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5806       if (operands[2] == const1_rtx)
5807         return "inc{l}\t%0";
5808       else
5809         {
5810           gcc_assert (operands[2] == constm1_rtx);
5811           return "dec{l}\t%0";
5812         }
5814     default:
5815       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5816       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5817          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5818       if (GET_CODE (operands[2]) == CONST_INT
5819           && (INTVAL (operands[2]) == 128
5820               || (INTVAL (operands[2]) < 0
5821                   && INTVAL (operands[2]) != -128)))
5822         {
5823           operands[2] = GEN_INT (-INTVAL (operands[2]));
5824           return "sub{l}\t{%2, %0|%0, %2}";
5825         }
5826       return "add{l}\t{%2, %0|%0, %2}";
5827     }
5829   [(set (attr "type")
5830      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5831         (const_string "incdec")
5832         (const_string "alu")))
5833    (set_attr "mode" "SI")])
5835 (define_expand "addhi3"
5836   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5837                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5838                             (match_operand:HI 2 "general_operand" "")))
5839               (clobber (reg:CC FLAGS_REG))])]
5840   "TARGET_HIMODE_MATH"
5841   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5843 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5844 ;; type optimizations enabled by define-splits.  This is not important
5845 ;; for PII, and in fact harmful because of partial register stalls.
5847 (define_insn "*addhi_1_lea"
5848   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5849         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5850                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5851    (clobber (reg:CC FLAGS_REG))]
5852   "!TARGET_PARTIAL_REG_STALL
5853    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5855   switch (get_attr_type (insn))
5856     {
5857     case TYPE_LEA:
5858       return "#";
5859     case TYPE_INCDEC:
5860       if (operands[2] == const1_rtx)
5861         return "inc{w}\t%0";
5862       else
5863         {
5864           gcc_assert (operands[2] == constm1_rtx);
5865           return "dec{w}\t%0";
5866         }
5868     default:
5869       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5870          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5871       if (GET_CODE (operands[2]) == CONST_INT
5872           && (INTVAL (operands[2]) == 128
5873               || (INTVAL (operands[2]) < 0
5874                   && INTVAL (operands[2]) != -128)))
5875         {
5876           operands[2] = GEN_INT (-INTVAL (operands[2]));
5877           return "sub{w}\t{%2, %0|%0, %2}";
5878         }
5879       return "add{w}\t{%2, %0|%0, %2}";
5880     }
5882   [(set (attr "type")
5883      (if_then_else (eq_attr "alternative" "2")
5884         (const_string "lea")
5885         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5886            (const_string "incdec")
5887            (const_string "alu"))))
5888    (set_attr "mode" "HI,HI,SI")])
5890 (define_insn "*addhi_1"
5891   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5892         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5893                  (match_operand:HI 2 "general_operand" "ri,rm")))
5894    (clobber (reg:CC FLAGS_REG))]
5895   "TARGET_PARTIAL_REG_STALL
5896    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5898   switch (get_attr_type (insn))
5899     {
5900     case TYPE_INCDEC:
5901       if (operands[2] == const1_rtx)
5902         return "inc{w}\t%0";
5903       else
5904         {
5905           gcc_assert (operands[2] == constm1_rtx);
5906           return "dec{w}\t%0";
5907         }
5909     default:
5910       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5911          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5912       if (GET_CODE (operands[2]) == CONST_INT
5913           && (INTVAL (operands[2]) == 128
5914               || (INTVAL (operands[2]) < 0
5915                   && INTVAL (operands[2]) != -128)))
5916         {
5917           operands[2] = GEN_INT (-INTVAL (operands[2]));
5918           return "sub{w}\t{%2, %0|%0, %2}";
5919         }
5920       return "add{w}\t{%2, %0|%0, %2}";
5921     }
5923   [(set (attr "type")
5924      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5925         (const_string "incdec")
5926         (const_string "alu")))
5927    (set_attr "mode" "HI")])
5929 (define_insn "*addhi_2"
5930   [(set (reg FLAGS_REG)
5931         (compare
5932           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5933                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5934           (const_int 0)))
5935    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5936         (plus:HI (match_dup 1) (match_dup 2)))]
5937   "ix86_match_ccmode (insn, CCGOCmode)
5938    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5940   switch (get_attr_type (insn))
5941     {
5942     case TYPE_INCDEC:
5943       if (operands[2] == const1_rtx)
5944         return "inc{w}\t%0";
5945       else
5946         {
5947           gcc_assert (operands[2] == constm1_rtx);
5948           return "dec{w}\t%0";
5949         }
5951     default:
5952       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5953          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5954       if (GET_CODE (operands[2]) == CONST_INT
5955           && (INTVAL (operands[2]) == 128
5956               || (INTVAL (operands[2]) < 0
5957                   && INTVAL (operands[2]) != -128)))
5958         {
5959           operands[2] = GEN_INT (-INTVAL (operands[2]));
5960           return "sub{w}\t{%2, %0|%0, %2}";
5961         }
5962       return "add{w}\t{%2, %0|%0, %2}";
5963     }
5965   [(set (attr "type")
5966      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5967         (const_string "incdec")
5968         (const_string "alu")))
5969    (set_attr "mode" "HI")])
5971 (define_insn "*addhi_3"
5972   [(set (reg FLAGS_REG)
5973         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5974                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5975    (clobber (match_scratch:HI 0 "=r"))]
5976   "ix86_match_ccmode (insn, CCZmode)
5977    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5979   switch (get_attr_type (insn))
5980     {
5981     case TYPE_INCDEC:
5982       if (operands[2] == const1_rtx)
5983         return "inc{w}\t%0";
5984       else
5985         {
5986           gcc_assert (operands[2] == constm1_rtx);
5987           return "dec{w}\t%0";
5988         }
5990     default:
5991       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5992          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5993       if (GET_CODE (operands[2]) == CONST_INT
5994           && (INTVAL (operands[2]) == 128
5995               || (INTVAL (operands[2]) < 0
5996                   && INTVAL (operands[2]) != -128)))
5997         {
5998           operands[2] = GEN_INT (-INTVAL (operands[2]));
5999           return "sub{w}\t{%2, %0|%0, %2}";
6000         }
6001       return "add{w}\t{%2, %0|%0, %2}";
6002     }
6004   [(set (attr "type")
6005      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6006         (const_string "incdec")
6007         (const_string "alu")))
6008    (set_attr "mode" "HI")])
6010 ; See comments above addsi_4 for details.
6011 (define_insn "*addhi_4"
6012   [(set (reg FLAGS_REG)
6013         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6014                  (match_operand:HI 2 "const_int_operand" "n")))
6015    (clobber (match_scratch:HI 0 "=rm"))]
6016   "ix86_match_ccmode (insn, CCGCmode)
6017    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6019   switch (get_attr_type (insn))
6020     {
6021     case TYPE_INCDEC:
6022       if (operands[2] == constm1_rtx)
6023         return "inc{w}\t%0";
6024       else
6025         {
6026           gcc_assert (operands[2] == const1_rtx);
6027           return "dec{w}\t%0";
6028         }
6030     default:
6031       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6032       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6033          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6034       if ((INTVAL (operands[2]) == -128
6035            || (INTVAL (operands[2]) > 0
6036                && INTVAL (operands[2]) != 128)))
6037         return "sub{w}\t{%2, %0|%0, %2}";
6038       operands[2] = GEN_INT (-INTVAL (operands[2]));
6039       return "add{w}\t{%2, %0|%0, %2}";
6040     }
6042   [(set (attr "type")
6043      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6044         (const_string "incdec")
6045         (const_string "alu")))
6046    (set_attr "mode" "SI")])
6049 (define_insn "*addhi_5"
6050   [(set (reg FLAGS_REG)
6051         (compare
6052           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6053                    (match_operand:HI 2 "general_operand" "rmni"))
6054           (const_int 0)))
6055    (clobber (match_scratch:HI 0 "=r"))]
6056   "ix86_match_ccmode (insn, CCGOCmode)
6057    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6059   switch (get_attr_type (insn))
6060     {
6061     case TYPE_INCDEC:
6062       if (operands[2] == const1_rtx)
6063         return "inc{w}\t%0";
6064       else
6065         {
6066           gcc_assert (operands[2] == constm1_rtx);
6067           return "dec{w}\t%0";
6068         }
6070     default:
6071       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6072          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6073       if (GET_CODE (operands[2]) == CONST_INT
6074           && (INTVAL (operands[2]) == 128
6075               || (INTVAL (operands[2]) < 0
6076                   && INTVAL (operands[2]) != -128)))
6077         {
6078           operands[2] = GEN_INT (-INTVAL (operands[2]));
6079           return "sub{w}\t{%2, %0|%0, %2}";
6080         }
6081       return "add{w}\t{%2, %0|%0, %2}";
6082     }
6084   [(set (attr "type")
6085      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6086         (const_string "incdec")
6087         (const_string "alu")))
6088    (set_attr "mode" "HI")])
6090 (define_expand "addqi3"
6091   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6092                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6093                             (match_operand:QI 2 "general_operand" "")))
6094               (clobber (reg:CC FLAGS_REG))])]
6095   "TARGET_QIMODE_MATH"
6096   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6098 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6099 (define_insn "*addqi_1_lea"
6100   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6101         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6102                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6103    (clobber (reg:CC FLAGS_REG))]
6104   "!TARGET_PARTIAL_REG_STALL
6105    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6107   int widen = (which_alternative == 2);
6108   switch (get_attr_type (insn))
6109     {
6110     case TYPE_LEA:
6111       return "#";
6112     case TYPE_INCDEC:
6113       if (operands[2] == const1_rtx)
6114         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6115       else
6116         {
6117           gcc_assert (operands[2] == constm1_rtx);
6118           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6119         }
6121     default:
6122       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6123          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6124       if (GET_CODE (operands[2]) == CONST_INT
6125           && (INTVAL (operands[2]) == 128
6126               || (INTVAL (operands[2]) < 0
6127                   && INTVAL (operands[2]) != -128)))
6128         {
6129           operands[2] = GEN_INT (-INTVAL (operands[2]));
6130           if (widen)
6131             return "sub{l}\t{%2, %k0|%k0, %2}";
6132           else
6133             return "sub{b}\t{%2, %0|%0, %2}";
6134         }
6135       if (widen)
6136         return "add{l}\t{%k2, %k0|%k0, %k2}";
6137       else
6138         return "add{b}\t{%2, %0|%0, %2}";
6139     }
6141   [(set (attr "type")
6142      (if_then_else (eq_attr "alternative" "3")
6143         (const_string "lea")
6144         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6145            (const_string "incdec")
6146            (const_string "alu"))))
6147    (set_attr "mode" "QI,QI,SI,SI")])
6149 (define_insn "*addqi_1"
6150   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6151         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6152                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6153    (clobber (reg:CC FLAGS_REG))]
6154   "TARGET_PARTIAL_REG_STALL
6155    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6157   int widen = (which_alternative == 2);
6158   switch (get_attr_type (insn))
6159     {
6160     case TYPE_INCDEC:
6161       if (operands[2] == const1_rtx)
6162         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6163       else
6164         {
6165           gcc_assert (operands[2] == constm1_rtx);
6166           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6167         }
6169     default:
6170       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6171          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6172       if (GET_CODE (operands[2]) == CONST_INT
6173           && (INTVAL (operands[2]) == 128
6174               || (INTVAL (operands[2]) < 0
6175                   && INTVAL (operands[2]) != -128)))
6176         {
6177           operands[2] = GEN_INT (-INTVAL (operands[2]));
6178           if (widen)
6179             return "sub{l}\t{%2, %k0|%k0, %2}";
6180           else
6181             return "sub{b}\t{%2, %0|%0, %2}";
6182         }
6183       if (widen)
6184         return "add{l}\t{%k2, %k0|%k0, %k2}";
6185       else
6186         return "add{b}\t{%2, %0|%0, %2}";
6187     }
6189   [(set (attr "type")
6190      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6191         (const_string "incdec")
6192         (const_string "alu")))
6193    (set_attr "mode" "QI,QI,SI")])
6195 (define_insn "*addqi_1_slp"
6196   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6197         (plus:QI (match_dup 0)
6198                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6199    (clobber (reg:CC FLAGS_REG))]
6200   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6201    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6203   switch (get_attr_type (insn))
6204     {
6205     case TYPE_INCDEC:
6206       if (operands[1] == const1_rtx)
6207         return "inc{b}\t%0";
6208       else
6209         {
6210           gcc_assert (operands[1] == constm1_rtx);
6211           return "dec{b}\t%0";
6212         }
6214     default:
6215       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6216       if (GET_CODE (operands[1]) == CONST_INT
6217           && INTVAL (operands[1]) < 0)
6218         {
6219           operands[1] = GEN_INT (-INTVAL (operands[1]));
6220           return "sub{b}\t{%1, %0|%0, %1}";
6221         }
6222       return "add{b}\t{%1, %0|%0, %1}";
6223     }
6225   [(set (attr "type")
6226      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6227         (const_string "incdec")
6228         (const_string "alu1")))
6229    (set (attr "memory")
6230      (if_then_else (match_operand 1 "memory_operand" "")
6231         (const_string "load")
6232         (const_string "none")))
6233    (set_attr "mode" "QI")])
6235 (define_insn "*addqi_2"
6236   [(set (reg FLAGS_REG)
6237         (compare
6238           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6239                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6240           (const_int 0)))
6241    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6242         (plus:QI (match_dup 1) (match_dup 2)))]
6243   "ix86_match_ccmode (insn, CCGOCmode)
6244    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6246   switch (get_attr_type (insn))
6247     {
6248     case TYPE_INCDEC:
6249       if (operands[2] == const1_rtx)
6250         return "inc{b}\t%0";
6251       else
6252         {
6253           gcc_assert (operands[2] == constm1_rtx
6254                       || (GET_CODE (operands[2]) == CONST_INT
6255                           && INTVAL (operands[2]) == 255));
6256           return "dec{b}\t%0";
6257         }
6259     default:
6260       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6261       if (GET_CODE (operands[2]) == CONST_INT
6262           && INTVAL (operands[2]) < 0)
6263         {
6264           operands[2] = GEN_INT (-INTVAL (operands[2]));
6265           return "sub{b}\t{%2, %0|%0, %2}";
6266         }
6267       return "add{b}\t{%2, %0|%0, %2}";
6268     }
6270   [(set (attr "type")
6271      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6272         (const_string "incdec")
6273         (const_string "alu")))
6274    (set_attr "mode" "QI")])
6276 (define_insn "*addqi_3"
6277   [(set (reg FLAGS_REG)
6278         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6279                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6280    (clobber (match_scratch:QI 0 "=q"))]
6281   "ix86_match_ccmode (insn, CCZmode)
6282    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6284   switch (get_attr_type (insn))
6285     {
6286     case TYPE_INCDEC:
6287       if (operands[2] == const1_rtx)
6288         return "inc{b}\t%0";
6289       else
6290         {
6291           gcc_assert (operands[2] == constm1_rtx
6292                       || (GET_CODE (operands[2]) == CONST_INT
6293                           && INTVAL (operands[2]) == 255));
6294           return "dec{b}\t%0";
6295         }
6297     default:
6298       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6299       if (GET_CODE (operands[2]) == CONST_INT
6300           && INTVAL (operands[2]) < 0)
6301         {
6302           operands[2] = GEN_INT (-INTVAL (operands[2]));
6303           return "sub{b}\t{%2, %0|%0, %2}";
6304         }
6305       return "add{b}\t{%2, %0|%0, %2}";
6306     }
6308   [(set (attr "type")
6309      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6310         (const_string "incdec")
6311         (const_string "alu")))
6312    (set_attr "mode" "QI")])
6314 ; See comments above addsi_4 for details.
6315 (define_insn "*addqi_4"
6316   [(set (reg FLAGS_REG)
6317         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6318                  (match_operand:QI 2 "const_int_operand" "n")))
6319    (clobber (match_scratch:QI 0 "=qm"))]
6320   "ix86_match_ccmode (insn, CCGCmode)
6321    && (INTVAL (operands[2]) & 0xff) != 0x80"
6323   switch (get_attr_type (insn))
6324     {
6325     case TYPE_INCDEC:
6326       if (operands[2] == constm1_rtx
6327           || (GET_CODE (operands[2]) == CONST_INT
6328               && INTVAL (operands[2]) == 255))
6329         return "inc{b}\t%0";
6330       else
6331         {
6332           gcc_assert (operands[2] == const1_rtx);
6333           return "dec{b}\t%0";
6334         }
6336     default:
6337       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6338       if (INTVAL (operands[2]) < 0)
6339         {
6340           operands[2] = GEN_INT (-INTVAL (operands[2]));
6341           return "add{b}\t{%2, %0|%0, %2}";
6342         }
6343       return "sub{b}\t{%2, %0|%0, %2}";
6344     }
6346   [(set (attr "type")
6347      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6348         (const_string "incdec")
6349         (const_string "alu")))
6350    (set_attr "mode" "QI")])
6353 (define_insn "*addqi_5"
6354   [(set (reg FLAGS_REG)
6355         (compare
6356           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6357                    (match_operand:QI 2 "general_operand" "qmni"))
6358           (const_int 0)))
6359    (clobber (match_scratch:QI 0 "=q"))]
6360   "ix86_match_ccmode (insn, CCGOCmode)
6361    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6363   switch (get_attr_type (insn))
6364     {
6365     case TYPE_INCDEC:
6366       if (operands[2] == const1_rtx)
6367         return "inc{b}\t%0";
6368       else
6369         {
6370           gcc_assert (operands[2] == constm1_rtx
6371                       || (GET_CODE (operands[2]) == CONST_INT
6372                           && INTVAL (operands[2]) == 255));
6373           return "dec{b}\t%0";
6374         }
6376     default:
6377       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6378       if (GET_CODE (operands[2]) == CONST_INT
6379           && INTVAL (operands[2]) < 0)
6380         {
6381           operands[2] = GEN_INT (-INTVAL (operands[2]));
6382           return "sub{b}\t{%2, %0|%0, %2}";
6383         }
6384       return "add{b}\t{%2, %0|%0, %2}";
6385     }
6387   [(set (attr "type")
6388      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389         (const_string "incdec")
6390         (const_string "alu")))
6391    (set_attr "mode" "QI")])
6394 (define_insn "addqi_ext_1"
6395   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6396                          (const_int 8)
6397                          (const_int 8))
6398         (plus:SI
6399           (zero_extract:SI
6400             (match_operand 1 "ext_register_operand" "0")
6401             (const_int 8)
6402             (const_int 8))
6403           (match_operand:QI 2 "general_operand" "Qmn")))
6404    (clobber (reg:CC FLAGS_REG))]
6405   "!TARGET_64BIT"
6407   switch (get_attr_type (insn))
6408     {
6409     case TYPE_INCDEC:
6410       if (operands[2] == const1_rtx)
6411         return "inc{b}\t%h0";
6412       else
6413         {
6414           gcc_assert (operands[2] == constm1_rtx
6415                       || (GET_CODE (operands[2]) == CONST_INT
6416                           && INTVAL (operands[2]) == 255));
6417           return "dec{b}\t%h0";
6418         }
6420     default:
6421       return "add{b}\t{%2, %h0|%h0, %2}";
6422     }
6424   [(set (attr "type")
6425      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6426         (const_string "incdec")
6427         (const_string "alu")))
6428    (set_attr "mode" "QI")])
6430 (define_insn "*addqi_ext_1_rex64"
6431   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6432                          (const_int 8)
6433                          (const_int 8))
6434         (plus:SI
6435           (zero_extract:SI
6436             (match_operand 1 "ext_register_operand" "0")
6437             (const_int 8)
6438             (const_int 8))
6439           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6440    (clobber (reg:CC FLAGS_REG))]
6441   "TARGET_64BIT"
6443   switch (get_attr_type (insn))
6444     {
6445     case TYPE_INCDEC:
6446       if (operands[2] == const1_rtx)
6447         return "inc{b}\t%h0";
6448       else
6449         {
6450           gcc_assert (operands[2] == constm1_rtx
6451                       || (GET_CODE (operands[2]) == CONST_INT
6452                           && INTVAL (operands[2]) == 255));
6453           return "dec{b}\t%h0";
6454         }
6456     default:
6457       return "add{b}\t{%2, %h0|%h0, %2}";
6458     }
6460   [(set (attr "type")
6461      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6462         (const_string "incdec")
6463         (const_string "alu")))
6464    (set_attr "mode" "QI")])
6466 (define_insn "*addqi_ext_2"
6467   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6468                          (const_int 8)
6469                          (const_int 8))
6470         (plus:SI
6471           (zero_extract:SI
6472             (match_operand 1 "ext_register_operand" "%0")
6473             (const_int 8)
6474             (const_int 8))
6475           (zero_extract:SI
6476             (match_operand 2 "ext_register_operand" "Q")
6477             (const_int 8)
6478             (const_int 8))))
6479    (clobber (reg:CC FLAGS_REG))]
6480   ""
6481   "add{b}\t{%h2, %h0|%h0, %h2}"
6482   [(set_attr "type" "alu")
6483    (set_attr "mode" "QI")])
6485 ;; The patterns that match these are at the end of this file.
6487 (define_expand "addxf3"
6488   [(set (match_operand:XF 0 "register_operand" "")
6489         (plus:XF (match_operand:XF 1 "register_operand" "")
6490                  (match_operand:XF 2 "register_operand" "")))]
6491   "TARGET_80387"
6492   "")
6494 (define_expand "adddf3"
6495   [(set (match_operand:DF 0 "register_operand" "")
6496         (plus:DF (match_operand:DF 1 "register_operand" "")
6497                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6498   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6499   "")
6501 (define_expand "addsf3"
6502   [(set (match_operand:SF 0 "register_operand" "")
6503         (plus:SF (match_operand:SF 1 "register_operand" "")
6504                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6505   "TARGET_80387 || TARGET_SSE_MATH"
6506   "")
6508 ;; Subtract instructions
6510 ;; %%% splits for subditi3
6512 (define_expand "subti3"
6513   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6514                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6515                              (match_operand:TI 2 "x86_64_general_operand" "")))
6516               (clobber (reg:CC FLAGS_REG))])]
6517   "TARGET_64BIT"
6518   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6520 (define_insn "*subti3_1"
6521   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6522         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6523                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6524    (clobber (reg:CC FLAGS_REG))]
6525   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6526   "#")
6528 (define_split
6529   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6530         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6531                   (match_operand:TI 2 "general_operand" "")))
6532    (clobber (reg:CC FLAGS_REG))]
6533   "TARGET_64BIT && reload_completed"
6534   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6535               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6536    (parallel [(set (match_dup 3)
6537                    (minus:DI (match_dup 4)
6538                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6539                                       (match_dup 5))))
6540               (clobber (reg:CC FLAGS_REG))])]
6541   "split_ti (operands+0, 1, operands+0, operands+3);
6542    split_ti (operands+1, 1, operands+1, operands+4);
6543    split_ti (operands+2, 1, operands+2, operands+5);")
6545 ;; %%% splits for subsidi3
6547 (define_expand "subdi3"
6548   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6549                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6550                              (match_operand:DI 2 "x86_64_general_operand" "")))
6551               (clobber (reg:CC FLAGS_REG))])]
6552   ""
6553   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6555 (define_insn "*subdi3_1"
6556   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6557         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6559    (clobber (reg:CC FLAGS_REG))]
6560   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6561   "#")
6563 (define_split
6564   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6565         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6566                   (match_operand:DI 2 "general_operand" "")))
6567    (clobber (reg:CC FLAGS_REG))]
6568   "!TARGET_64BIT && reload_completed"
6569   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6570               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6571    (parallel [(set (match_dup 3)
6572                    (minus:SI (match_dup 4)
6573                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6574                                       (match_dup 5))))
6575               (clobber (reg:CC FLAGS_REG))])]
6576   "split_di (operands+0, 1, operands+0, operands+3);
6577    split_di (operands+1, 1, operands+1, operands+4);
6578    split_di (operands+2, 1, operands+2, operands+5);")
6580 (define_insn "subdi3_carry_rex64"
6581   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6582           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6583             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6584                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6585    (clobber (reg:CC FLAGS_REG))]
6586   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6587   "sbb{q}\t{%2, %0|%0, %2}"
6588   [(set_attr "type" "alu")
6589    (set_attr "pent_pair" "pu")
6590    (set_attr "mode" "DI")])
6592 (define_insn "*subdi_1_rex64"
6593   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6594         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6595                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6596    (clobber (reg:CC FLAGS_REG))]
6597   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6598   "sub{q}\t{%2, %0|%0, %2}"
6599   [(set_attr "type" "alu")
6600    (set_attr "mode" "DI")])
6602 (define_insn "*subdi_2_rex64"
6603   [(set (reg FLAGS_REG)
6604         (compare
6605           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6606                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6607           (const_int 0)))
6608    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6609         (minus:DI (match_dup 1) (match_dup 2)))]
6610   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6611    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6612   "sub{q}\t{%2, %0|%0, %2}"
6613   [(set_attr "type" "alu")
6614    (set_attr "mode" "DI")])
6616 (define_insn "*subdi_3_rex63"
6617   [(set (reg FLAGS_REG)
6618         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6619                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6620    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6621         (minus:DI (match_dup 1) (match_dup 2)))]
6622   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6623    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6624   "sub{q}\t{%2, %0|%0, %2}"
6625   [(set_attr "type" "alu")
6626    (set_attr "mode" "DI")])
6628 (define_insn "subqi3_carry"
6629   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6630           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6631             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6632                (match_operand:QI 2 "general_operand" "qi,qm"))))
6633    (clobber (reg:CC FLAGS_REG))]
6634   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6635   "sbb{b}\t{%2, %0|%0, %2}"
6636   [(set_attr "type" "alu")
6637    (set_attr "pent_pair" "pu")
6638    (set_attr "mode" "QI")])
6640 (define_insn "subhi3_carry"
6641   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6642           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6643             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6644                (match_operand:HI 2 "general_operand" "ri,rm"))))
6645    (clobber (reg:CC FLAGS_REG))]
6646   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6647   "sbb{w}\t{%2, %0|%0, %2}"
6648   [(set_attr "type" "alu")
6649    (set_attr "pent_pair" "pu")
6650    (set_attr "mode" "HI")])
6652 (define_insn "subsi3_carry"
6653   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6654           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6655             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6656                (match_operand:SI 2 "general_operand" "ri,rm"))))
6657    (clobber (reg:CC FLAGS_REG))]
6658   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6659   "sbb{l}\t{%2, %0|%0, %2}"
6660   [(set_attr "type" "alu")
6661    (set_attr "pent_pair" "pu")
6662    (set_attr "mode" "SI")])
6664 (define_insn "subsi3_carry_zext"
6665   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6666           (zero_extend:DI
6667             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6668               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6669                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6670    (clobber (reg:CC FLAGS_REG))]
6671   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6672   "sbb{l}\t{%2, %k0|%k0, %2}"
6673   [(set_attr "type" "alu")
6674    (set_attr "pent_pair" "pu")
6675    (set_attr "mode" "SI")])
6677 (define_expand "subsi3"
6678   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6679                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6680                              (match_operand:SI 2 "general_operand" "")))
6681               (clobber (reg:CC FLAGS_REG))])]
6682   ""
6683   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6685 (define_insn "*subsi_1"
6686   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6687         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6688                   (match_operand:SI 2 "general_operand" "ri,rm")))
6689    (clobber (reg:CC FLAGS_REG))]
6690   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6691   "sub{l}\t{%2, %0|%0, %2}"
6692   [(set_attr "type" "alu")
6693    (set_attr "mode" "SI")])
6695 (define_insn "*subsi_1_zext"
6696   [(set (match_operand:DI 0 "register_operand" "=r")
6697         (zero_extend:DI
6698           (minus:SI (match_operand:SI 1 "register_operand" "0")
6699                     (match_operand:SI 2 "general_operand" "rim"))))
6700    (clobber (reg:CC FLAGS_REG))]
6701   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6702   "sub{l}\t{%2, %k0|%k0, %2}"
6703   [(set_attr "type" "alu")
6704    (set_attr "mode" "SI")])
6706 (define_insn "*subsi_2"
6707   [(set (reg FLAGS_REG)
6708         (compare
6709           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6710                     (match_operand:SI 2 "general_operand" "ri,rm"))
6711           (const_int 0)))
6712    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6713         (minus:SI (match_dup 1) (match_dup 2)))]
6714   "ix86_match_ccmode (insn, CCGOCmode)
6715    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6716   "sub{l}\t{%2, %0|%0, %2}"
6717   [(set_attr "type" "alu")
6718    (set_attr "mode" "SI")])
6720 (define_insn "*subsi_2_zext"
6721   [(set (reg FLAGS_REG)
6722         (compare
6723           (minus:SI (match_operand:SI 1 "register_operand" "0")
6724                     (match_operand:SI 2 "general_operand" "rim"))
6725           (const_int 0)))
6726    (set (match_operand:DI 0 "register_operand" "=r")
6727         (zero_extend:DI
6728           (minus:SI (match_dup 1)
6729                     (match_dup 2))))]
6730   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6731    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6732   "sub{l}\t{%2, %k0|%k0, %2}"
6733   [(set_attr "type" "alu")
6734    (set_attr "mode" "SI")])
6736 (define_insn "*subsi_3"
6737   [(set (reg FLAGS_REG)
6738         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6739                  (match_operand:SI 2 "general_operand" "ri,rm")))
6740    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6741         (minus:SI (match_dup 1) (match_dup 2)))]
6742   "ix86_match_ccmode (insn, CCmode)
6743    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6744   "sub{l}\t{%2, %0|%0, %2}"
6745   [(set_attr "type" "alu")
6746    (set_attr "mode" "SI")])
6748 (define_insn "*subsi_3_zext"
6749   [(set (reg FLAGS_REG)
6750         (compare (match_operand:SI 1 "register_operand" "0")
6751                  (match_operand:SI 2 "general_operand" "rim")))
6752    (set (match_operand:DI 0 "register_operand" "=r")
6753         (zero_extend:DI
6754           (minus:SI (match_dup 1)
6755                     (match_dup 2))))]
6756   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6757    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6758   "sub{l}\t{%2, %1|%1, %2}"
6759   [(set_attr "type" "alu")
6760    (set_attr "mode" "DI")])
6762 (define_expand "subhi3"
6763   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6764                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6765                              (match_operand:HI 2 "general_operand" "")))
6766               (clobber (reg:CC FLAGS_REG))])]
6767   "TARGET_HIMODE_MATH"
6768   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6770 (define_insn "*subhi_1"
6771   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6772         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6773                   (match_operand:HI 2 "general_operand" "ri,rm")))
6774    (clobber (reg:CC FLAGS_REG))]
6775   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6776   "sub{w}\t{%2, %0|%0, %2}"
6777   [(set_attr "type" "alu")
6778    (set_attr "mode" "HI")])
6780 (define_insn "*subhi_2"
6781   [(set (reg FLAGS_REG)
6782         (compare
6783           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6784                     (match_operand:HI 2 "general_operand" "ri,rm"))
6785           (const_int 0)))
6786    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6787         (minus:HI (match_dup 1) (match_dup 2)))]
6788   "ix86_match_ccmode (insn, CCGOCmode)
6789    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6790   "sub{w}\t{%2, %0|%0, %2}"
6791   [(set_attr "type" "alu")
6792    (set_attr "mode" "HI")])
6794 (define_insn "*subhi_3"
6795   [(set (reg FLAGS_REG)
6796         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6797                  (match_operand:HI 2 "general_operand" "ri,rm")))
6798    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6799         (minus:HI (match_dup 1) (match_dup 2)))]
6800   "ix86_match_ccmode (insn, CCmode)
6801    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6802   "sub{w}\t{%2, %0|%0, %2}"
6803   [(set_attr "type" "alu")
6804    (set_attr "mode" "HI")])
6806 (define_expand "subqi3"
6807   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6808                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6809                              (match_operand:QI 2 "general_operand" "")))
6810               (clobber (reg:CC FLAGS_REG))])]
6811   "TARGET_QIMODE_MATH"
6812   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6814 (define_insn "*subqi_1"
6815   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6816         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6817                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6818    (clobber (reg:CC FLAGS_REG))]
6819   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6820   "sub{b}\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "alu")
6822    (set_attr "mode" "QI")])
6824 (define_insn "*subqi_1_slp"
6825   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6826         (minus:QI (match_dup 0)
6827                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6828    (clobber (reg:CC FLAGS_REG))]
6829   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6830    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6831   "sub{b}\t{%1, %0|%0, %1}"
6832   [(set_attr "type" "alu1")
6833    (set_attr "mode" "QI")])
6835 (define_insn "*subqi_2"
6836   [(set (reg FLAGS_REG)
6837         (compare
6838           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6839                     (match_operand:QI 2 "general_operand" "qi,qm"))
6840           (const_int 0)))
6841    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6842         (minus:HI (match_dup 1) (match_dup 2)))]
6843   "ix86_match_ccmode (insn, CCGOCmode)
6844    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6845   "sub{b}\t{%2, %0|%0, %2}"
6846   [(set_attr "type" "alu")
6847    (set_attr "mode" "QI")])
6849 (define_insn "*subqi_3"
6850   [(set (reg FLAGS_REG)
6851         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6852                  (match_operand:QI 2 "general_operand" "qi,qm")))
6853    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6854         (minus:HI (match_dup 1) (match_dup 2)))]
6855   "ix86_match_ccmode (insn, CCmode)
6856    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6857   "sub{b}\t{%2, %0|%0, %2}"
6858   [(set_attr "type" "alu")
6859    (set_attr "mode" "QI")])
6861 ;; The patterns that match these are at the end of this file.
6863 (define_expand "subxf3"
6864   [(set (match_operand:XF 0 "register_operand" "")
6865         (minus:XF (match_operand:XF 1 "register_operand" "")
6866                   (match_operand:XF 2 "register_operand" "")))]
6867   "TARGET_80387"
6868   "")
6870 (define_expand "subdf3"
6871   [(set (match_operand:DF 0 "register_operand" "")
6872         (minus:DF (match_operand:DF 1 "register_operand" "")
6873                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6874   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6875   "")
6877 (define_expand "subsf3"
6878   [(set (match_operand:SF 0 "register_operand" "")
6879         (minus:SF (match_operand:SF 1 "register_operand" "")
6880                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6881   "TARGET_80387 || TARGET_SSE_MATH"
6882   "")
6884 ;; Multiply instructions
6886 (define_expand "muldi3"
6887   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6888                    (mult:DI (match_operand:DI 1 "register_operand" "")
6889                             (match_operand:DI 2 "x86_64_general_operand" "")))
6890               (clobber (reg:CC FLAGS_REG))])]
6891   "TARGET_64BIT"
6892   "")
6894 (define_insn "*muldi3_1_rex64"
6895   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6896         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6897                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6898    (clobber (reg:CC FLAGS_REG))]
6899   "TARGET_64BIT
6900    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6901   "@
6902    imul{q}\t{%2, %1, %0|%0, %1, %2}
6903    imul{q}\t{%2, %1, %0|%0, %1, %2}
6904    imul{q}\t{%2, %0|%0, %2}"
6905   [(set_attr "type" "imul")
6906    (set_attr "prefix_0f" "0,0,1")
6907    (set (attr "athlon_decode")
6908         (cond [(eq_attr "cpu" "athlon")
6909                   (const_string "vector")
6910                (eq_attr "alternative" "1")
6911                   (const_string "vector")
6912                (and (eq_attr "alternative" "2")
6913                     (match_operand 1 "memory_operand" ""))
6914                   (const_string "vector")]
6915               (const_string "direct")))
6916    (set_attr "mode" "DI")])
6918 (define_expand "mulsi3"
6919   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6920                    (mult:SI (match_operand:SI 1 "register_operand" "")
6921                             (match_operand:SI 2 "general_operand" "")))
6922               (clobber (reg:CC FLAGS_REG))])]
6923   ""
6924   "")
6926 (define_insn "*mulsi3_1"
6927   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6928         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6929                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6930    (clobber (reg:CC FLAGS_REG))]
6931   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6932   "@
6933    imul{l}\t{%2, %1, %0|%0, %1, %2}
6934    imul{l}\t{%2, %1, %0|%0, %1, %2}
6935    imul{l}\t{%2, %0|%0, %2}"
6936   [(set_attr "type" "imul")
6937    (set_attr "prefix_0f" "0,0,1")
6938    (set (attr "athlon_decode")
6939         (cond [(eq_attr "cpu" "athlon")
6940                   (const_string "vector")
6941                (eq_attr "alternative" "1")
6942                   (const_string "vector")
6943                (and (eq_attr "alternative" "2")
6944                     (match_operand 1 "memory_operand" ""))
6945                   (const_string "vector")]
6946               (const_string "direct")))
6947    (set_attr "mode" "SI")])
6949 (define_insn "*mulsi3_1_zext"
6950   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6951         (zero_extend:DI
6952           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6953                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6954    (clobber (reg:CC FLAGS_REG))]
6955   "TARGET_64BIT
6956    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6957   "@
6958    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6959    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6960    imul{l}\t{%2, %k0|%k0, %2}"
6961   [(set_attr "type" "imul")
6962    (set_attr "prefix_0f" "0,0,1")
6963    (set (attr "athlon_decode")
6964         (cond [(eq_attr "cpu" "athlon")
6965                   (const_string "vector")
6966                (eq_attr "alternative" "1")
6967                   (const_string "vector")
6968                (and (eq_attr "alternative" "2")
6969                     (match_operand 1 "memory_operand" ""))
6970                   (const_string "vector")]
6971               (const_string "direct")))
6972    (set_attr "mode" "SI")])
6974 (define_expand "mulhi3"
6975   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6976                    (mult:HI (match_operand:HI 1 "register_operand" "")
6977                             (match_operand:HI 2 "general_operand" "")))
6978               (clobber (reg:CC FLAGS_REG))])]
6979   "TARGET_HIMODE_MATH"
6980   "")
6982 (define_insn "*mulhi3_1"
6983   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6984         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6985                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6986    (clobber (reg:CC FLAGS_REG))]
6987   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6988   "@
6989    imul{w}\t{%2, %1, %0|%0, %1, %2}
6990    imul{w}\t{%2, %1, %0|%0, %1, %2}
6991    imul{w}\t{%2, %0|%0, %2}"
6992   [(set_attr "type" "imul")
6993    (set_attr "prefix_0f" "0,0,1")
6994    (set (attr "athlon_decode")
6995         (cond [(eq_attr "cpu" "athlon")
6996                   (const_string "vector")
6997                (eq_attr "alternative" "1,2")
6998                   (const_string "vector")]
6999               (const_string "direct")))
7000    (set_attr "mode" "HI")])
7002 (define_expand "mulqi3"
7003   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7004                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7005                             (match_operand:QI 2 "register_operand" "")))
7006               (clobber (reg:CC FLAGS_REG))])]
7007   "TARGET_QIMODE_MATH"
7008   "")
7010 (define_insn "*mulqi3_1"
7011   [(set (match_operand:QI 0 "register_operand" "=a")
7012         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7013                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7014    (clobber (reg:CC FLAGS_REG))]
7015   "TARGET_QIMODE_MATH
7016    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7017   "mul{b}\t%2"
7018   [(set_attr "type" "imul")
7019    (set_attr "length_immediate" "0")
7020    (set (attr "athlon_decode")
7021      (if_then_else (eq_attr "cpu" "athlon")
7022         (const_string "vector")
7023         (const_string "direct")))
7024    (set_attr "mode" "QI")])
7026 (define_expand "umulqihi3"
7027   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7028                    (mult:HI (zero_extend:HI
7029                               (match_operand:QI 1 "nonimmediate_operand" ""))
7030                             (zero_extend:HI
7031                               (match_operand:QI 2 "register_operand" ""))))
7032               (clobber (reg:CC FLAGS_REG))])]
7033   "TARGET_QIMODE_MATH"
7034   "")
7036 (define_insn "*umulqihi3_1"
7037   [(set (match_operand:HI 0 "register_operand" "=a")
7038         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7039                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7040    (clobber (reg:CC FLAGS_REG))]
7041   "TARGET_QIMODE_MATH
7042    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7043   "mul{b}\t%2"
7044   [(set_attr "type" "imul")
7045    (set_attr "length_immediate" "0")
7046    (set (attr "athlon_decode")
7047      (if_then_else (eq_attr "cpu" "athlon")
7048         (const_string "vector")
7049         (const_string "direct")))
7050    (set_attr "mode" "QI")])
7052 (define_expand "mulqihi3"
7053   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7054                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7055                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7056               (clobber (reg:CC FLAGS_REG))])]
7057   "TARGET_QIMODE_MATH"
7058   "")
7060 (define_insn "*mulqihi3_insn"
7061   [(set (match_operand:HI 0 "register_operand" "=a")
7062         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7063                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7064    (clobber (reg:CC FLAGS_REG))]
7065   "TARGET_QIMODE_MATH
7066    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7067   "imul{b}\t%2"
7068   [(set_attr "type" "imul")
7069    (set_attr "length_immediate" "0")
7070    (set (attr "athlon_decode")
7071      (if_then_else (eq_attr "cpu" "athlon")
7072         (const_string "vector")
7073         (const_string "direct")))
7074    (set_attr "mode" "QI")])
7076 (define_expand "umulditi3"
7077   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7078                    (mult:TI (zero_extend:TI
7079                               (match_operand:DI 1 "nonimmediate_operand" ""))
7080                             (zero_extend:TI
7081                               (match_operand:DI 2 "register_operand" ""))))
7082               (clobber (reg:CC FLAGS_REG))])]
7083   "TARGET_64BIT"
7084   "")
7086 (define_insn "*umulditi3_insn"
7087   [(set (match_operand:TI 0 "register_operand" "=A")
7088         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7089                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7090    (clobber (reg:CC FLAGS_REG))]
7091   "TARGET_64BIT
7092    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7093   "mul{q}\t%2"
7094   [(set_attr "type" "imul")
7095    (set_attr "length_immediate" "0")
7096    (set (attr "athlon_decode")
7097      (if_then_else (eq_attr "cpu" "athlon")
7098         (const_string "vector")
7099         (const_string "double")))
7100    (set_attr "mode" "DI")])
7102 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7103 (define_expand "umulsidi3"
7104   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7105                    (mult:DI (zero_extend:DI
7106                               (match_operand:SI 1 "nonimmediate_operand" ""))
7107                             (zero_extend:DI
7108                               (match_operand:SI 2 "register_operand" ""))))
7109               (clobber (reg:CC FLAGS_REG))])]
7110   "!TARGET_64BIT"
7111   "")
7113 (define_insn "*umulsidi3_insn"
7114   [(set (match_operand:DI 0 "register_operand" "=A")
7115         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7116                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7117    (clobber (reg:CC FLAGS_REG))]
7118   "!TARGET_64BIT
7119    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7120   "mul{l}\t%2"
7121   [(set_attr "type" "imul")
7122    (set_attr "length_immediate" "0")
7123    (set (attr "athlon_decode")
7124      (if_then_else (eq_attr "cpu" "athlon")
7125         (const_string "vector")
7126         (const_string "double")))
7127    (set_attr "mode" "SI")])
7129 (define_expand "mulditi3"
7130   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7131                    (mult:TI (sign_extend:TI
7132                               (match_operand:DI 1 "nonimmediate_operand" ""))
7133                             (sign_extend:TI
7134                               (match_operand:DI 2 "register_operand" ""))))
7135               (clobber (reg:CC FLAGS_REG))])]
7136   "TARGET_64BIT"
7137   "")
7139 (define_insn "*mulditi3_insn"
7140   [(set (match_operand:TI 0 "register_operand" "=A")
7141         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7142                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7143    (clobber (reg:CC FLAGS_REG))]
7144   "TARGET_64BIT
7145    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7146   "imul{q}\t%2"
7147   [(set_attr "type" "imul")
7148    (set_attr "length_immediate" "0")
7149    (set (attr "athlon_decode")
7150      (if_then_else (eq_attr "cpu" "athlon")
7151         (const_string "vector")
7152         (const_string "double")))
7153    (set_attr "mode" "DI")])
7155 (define_expand "mulsidi3"
7156   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7157                    (mult:DI (sign_extend:DI
7158                               (match_operand:SI 1 "nonimmediate_operand" ""))
7159                             (sign_extend:DI
7160                               (match_operand:SI 2 "register_operand" ""))))
7161               (clobber (reg:CC FLAGS_REG))])]
7162   "!TARGET_64BIT"
7163   "")
7165 (define_insn "*mulsidi3_insn"
7166   [(set (match_operand:DI 0 "register_operand" "=A")
7167         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7168                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7169    (clobber (reg:CC FLAGS_REG))]
7170   "!TARGET_64BIT
7171    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7172   "imul{l}\t%2"
7173   [(set_attr "type" "imul")
7174    (set_attr "length_immediate" "0")
7175    (set (attr "athlon_decode")
7176      (if_then_else (eq_attr "cpu" "athlon")
7177         (const_string "vector")
7178         (const_string "double")))
7179    (set_attr "mode" "SI")])
7181 (define_expand "umuldi3_highpart"
7182   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7183                    (truncate:DI
7184                      (lshiftrt:TI
7185                        (mult:TI (zero_extend:TI
7186                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7187                                 (zero_extend:TI
7188                                   (match_operand:DI 2 "register_operand" "")))
7189                        (const_int 64))))
7190               (clobber (match_scratch:DI 3 ""))
7191               (clobber (reg:CC FLAGS_REG))])]
7192   "TARGET_64BIT"
7193   "")
7195 (define_insn "*umuldi3_highpart_rex64"
7196   [(set (match_operand:DI 0 "register_operand" "=d")
7197         (truncate:DI
7198           (lshiftrt:TI
7199             (mult:TI (zero_extend:TI
7200                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7201                      (zero_extend:TI
7202                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7203             (const_int 64))))
7204    (clobber (match_scratch:DI 3 "=1"))
7205    (clobber (reg:CC FLAGS_REG))]
7206   "TARGET_64BIT
7207    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7208   "mul{q}\t%2"
7209   [(set_attr "type" "imul")
7210    (set_attr "length_immediate" "0")
7211    (set (attr "athlon_decode")
7212      (if_then_else (eq_attr "cpu" "athlon")
7213         (const_string "vector")
7214         (const_string "double")))
7215    (set_attr "mode" "DI")])
7217 (define_expand "umulsi3_highpart"
7218   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7219                    (truncate:SI
7220                      (lshiftrt:DI
7221                        (mult:DI (zero_extend:DI
7222                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7223                                 (zero_extend:DI
7224                                   (match_operand:SI 2 "register_operand" "")))
7225                        (const_int 32))))
7226               (clobber (match_scratch:SI 3 ""))
7227               (clobber (reg:CC FLAGS_REG))])]
7228   ""
7229   "")
7231 (define_insn "*umulsi3_highpart_insn"
7232   [(set (match_operand:SI 0 "register_operand" "=d")
7233         (truncate:SI
7234           (lshiftrt:DI
7235             (mult:DI (zero_extend:DI
7236                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7237                      (zero_extend:DI
7238                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7239             (const_int 32))))
7240    (clobber (match_scratch:SI 3 "=1"))
7241    (clobber (reg:CC FLAGS_REG))]
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_insn "*umulsi3_highpart_zext"
7253   [(set (match_operand:DI 0 "register_operand" "=d")
7254         (zero_extend:DI (truncate:SI
7255           (lshiftrt:DI
7256             (mult:DI (zero_extend:DI
7257                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7258                      (zero_extend:DI
7259                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7260             (const_int 32)))))
7261    (clobber (match_scratch:SI 3 "=1"))
7262    (clobber (reg:CC FLAGS_REG))]
7263   "TARGET_64BIT
7264    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7265   "mul{l}\t%2"
7266   [(set_attr "type" "imul")
7267    (set_attr "length_immediate" "0")
7268    (set (attr "athlon_decode")
7269      (if_then_else (eq_attr "cpu" "athlon")
7270         (const_string "vector")
7271         (const_string "double")))
7272    (set_attr "mode" "SI")])
7274 (define_expand "smuldi3_highpart"
7275   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7276                    (truncate:DI
7277                      (lshiftrt:TI
7278                        (mult:TI (sign_extend:TI
7279                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7280                                 (sign_extend:TI
7281                                   (match_operand:DI 2 "register_operand" "")))
7282                        (const_int 64))))
7283               (clobber (match_scratch:DI 3 ""))
7284               (clobber (reg:CC FLAGS_REG))])]
7285   "TARGET_64BIT"
7286   "")
7288 (define_insn "*smuldi3_highpart_rex64"
7289   [(set (match_operand:DI 0 "register_operand" "=d")
7290         (truncate:DI
7291           (lshiftrt:TI
7292             (mult:TI (sign_extend:TI
7293                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7294                      (sign_extend:TI
7295                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7296             (const_int 64))))
7297    (clobber (match_scratch:DI 3 "=1"))
7298    (clobber (reg:CC FLAGS_REG))]
7299   "TARGET_64BIT
7300    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7301   "imul{q}\t%2"
7302   [(set_attr "type" "imul")
7303    (set (attr "athlon_decode")
7304      (if_then_else (eq_attr "cpu" "athlon")
7305         (const_string "vector")
7306         (const_string "double")))
7307    (set_attr "mode" "DI")])
7309 (define_expand "smulsi3_highpart"
7310   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7311                    (truncate:SI
7312                      (lshiftrt:DI
7313                        (mult:DI (sign_extend:DI
7314                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7315                                 (sign_extend:DI
7316                                   (match_operand:SI 2 "register_operand" "")))
7317                        (const_int 32))))
7318               (clobber (match_scratch:SI 3 ""))
7319               (clobber (reg:CC FLAGS_REG))])]
7320   ""
7321   "")
7323 (define_insn "*smulsi3_highpart_insn"
7324   [(set (match_operand:SI 0 "register_operand" "=d")
7325         (truncate:SI
7326           (lshiftrt:DI
7327             (mult:DI (sign_extend:DI
7328                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7329                      (sign_extend:DI
7330                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7331             (const_int 32))))
7332    (clobber (match_scratch:SI 3 "=1"))
7333    (clobber (reg:CC FLAGS_REG))]
7334   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7335   "imul{l}\t%2"
7336   [(set_attr "type" "imul")
7337    (set (attr "athlon_decode")
7338      (if_then_else (eq_attr "cpu" "athlon")
7339         (const_string "vector")
7340         (const_string "double")))
7341    (set_attr "mode" "SI")])
7343 (define_insn "*smulsi3_highpart_zext"
7344   [(set (match_operand:DI 0 "register_operand" "=d")
7345         (zero_extend:DI (truncate:SI
7346           (lshiftrt:DI
7347             (mult:DI (sign_extend:DI
7348                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7349                      (sign_extend:DI
7350                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7351             (const_int 32)))))
7352    (clobber (match_scratch:SI 3 "=1"))
7353    (clobber (reg:CC FLAGS_REG))]
7354   "TARGET_64BIT
7355    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7356   "imul{l}\t%2"
7357   [(set_attr "type" "imul")
7358    (set (attr "athlon_decode")
7359      (if_then_else (eq_attr "cpu" "athlon")
7360         (const_string "vector")
7361         (const_string "double")))
7362    (set_attr "mode" "SI")])
7364 ;; The patterns that match these are at the end of this file.
7366 (define_expand "mulxf3"
7367   [(set (match_operand:XF 0 "register_operand" "")
7368         (mult:XF (match_operand:XF 1 "register_operand" "")
7369                  (match_operand:XF 2 "register_operand" "")))]
7370   "TARGET_80387"
7371   "")
7373 (define_expand "muldf3"
7374   [(set (match_operand:DF 0 "register_operand" "")
7375         (mult:DF (match_operand:DF 1 "register_operand" "")
7376                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7377   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7378   "")
7380 (define_expand "mulsf3"
7381   [(set (match_operand:SF 0 "register_operand" "")
7382         (mult:SF (match_operand:SF 1 "register_operand" "")
7383                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7384   "TARGET_80387 || TARGET_SSE_MATH"
7385   "")
7387 ;; Divide instructions
7389 (define_insn "divqi3"
7390   [(set (match_operand:QI 0 "register_operand" "=a")
7391         (div:QI (match_operand:HI 1 "register_operand" "0")
7392                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7393    (clobber (reg:CC FLAGS_REG))]
7394   "TARGET_QIMODE_MATH"
7395   "idiv{b}\t%2"
7396   [(set_attr "type" "idiv")
7397    (set_attr "mode" "QI")])
7399 (define_insn "udivqi3"
7400   [(set (match_operand:QI 0 "register_operand" "=a")
7401         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7402                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7403    (clobber (reg:CC FLAGS_REG))]
7404   "TARGET_QIMODE_MATH"
7405   "div{b}\t%2"
7406   [(set_attr "type" "idiv")
7407    (set_attr "mode" "QI")])
7409 ;; The patterns that match these are at the end of this file.
7411 (define_expand "divxf3"
7412   [(set (match_operand:XF 0 "register_operand" "")
7413         (div:XF (match_operand:XF 1 "register_operand" "")
7414                 (match_operand:XF 2 "register_operand" "")))]
7415   "TARGET_80387"
7416   "")
7418 (define_expand "divdf3"
7419   [(set (match_operand:DF 0 "register_operand" "")
7420         (div:DF (match_operand:DF 1 "register_operand" "")
7421                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7422    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7423    "")
7425 (define_expand "divsf3"
7426   [(set (match_operand:SF 0 "register_operand" "")
7427         (div:SF (match_operand:SF 1 "register_operand" "")
7428                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7429   "TARGET_80387 || TARGET_SSE_MATH"
7430   "")
7432 ;; Remainder instructions.
7434 (define_expand "divmoddi4"
7435   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7436                    (div:DI (match_operand:DI 1 "register_operand" "")
7437                            (match_operand:DI 2 "nonimmediate_operand" "")))
7438               (set (match_operand:DI 3 "register_operand" "")
7439                    (mod:DI (match_dup 1) (match_dup 2)))
7440               (clobber (reg:CC FLAGS_REG))])]
7441   "TARGET_64BIT"
7442   "")
7444 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7445 ;; Penalize eax case slightly because it results in worse scheduling
7446 ;; of code.
7447 (define_insn "*divmoddi4_nocltd_rex64"
7448   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7449         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7450                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7451    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7452         (mod:DI (match_dup 2) (match_dup 3)))
7453    (clobber (reg:CC FLAGS_REG))]
7454   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7455   "#"
7456   [(set_attr "type" "multi")])
7458 (define_insn "*divmoddi4_cltd_rex64"
7459   [(set (match_operand:DI 0 "register_operand" "=a")
7460         (div:DI (match_operand:DI 2 "register_operand" "a")
7461                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7462    (set (match_operand:DI 1 "register_operand" "=&d")
7463         (mod:DI (match_dup 2) (match_dup 3)))
7464    (clobber (reg:CC FLAGS_REG))]
7465   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7466   "#"
7467   [(set_attr "type" "multi")])
7469 (define_insn "*divmoddi_noext_rex64"
7470   [(set (match_operand:DI 0 "register_operand" "=a")
7471         (div:DI (match_operand:DI 1 "register_operand" "0")
7472                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7473    (set (match_operand:DI 3 "register_operand" "=d")
7474         (mod:DI (match_dup 1) (match_dup 2)))
7475    (use (match_operand:DI 4 "register_operand" "3"))
7476    (clobber (reg:CC FLAGS_REG))]
7477   "TARGET_64BIT"
7478   "idiv{q}\t%2"
7479   [(set_attr "type" "idiv")
7480    (set_attr "mode" "DI")])
7482 (define_split
7483   [(set (match_operand:DI 0 "register_operand" "")
7484         (div:DI (match_operand:DI 1 "register_operand" "")
7485                 (match_operand:DI 2 "nonimmediate_operand" "")))
7486    (set (match_operand:DI 3 "register_operand" "")
7487         (mod:DI (match_dup 1) (match_dup 2)))
7488    (clobber (reg:CC FLAGS_REG))]
7489   "TARGET_64BIT && reload_completed"
7490   [(parallel [(set (match_dup 3)
7491                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7492               (clobber (reg:CC FLAGS_REG))])
7493    (parallel [(set (match_dup 0)
7494                    (div:DI (reg:DI 0) (match_dup 2)))
7495               (set (match_dup 3)
7496                    (mod:DI (reg:DI 0) (match_dup 2)))
7497               (use (match_dup 3))
7498               (clobber (reg:CC FLAGS_REG))])]
7500   /* Avoid use of cltd in favor of a mov+shift.  */
7501   if (!TARGET_USE_CLTD && !optimize_size)
7502     {
7503       if (true_regnum (operands[1]))
7504         emit_move_insn (operands[0], operands[1]);
7505       else
7506         emit_move_insn (operands[3], operands[1]);
7507       operands[4] = operands[3];
7508     }
7509   else
7510     {
7511       gcc_assert (!true_regnum (operands[1]));
7512       operands[4] = operands[1];
7513     }
7517 (define_expand "divmodsi4"
7518   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7519                    (div:SI (match_operand:SI 1 "register_operand" "")
7520                            (match_operand:SI 2 "nonimmediate_operand" "")))
7521               (set (match_operand:SI 3 "register_operand" "")
7522                    (mod:SI (match_dup 1) (match_dup 2)))
7523               (clobber (reg:CC FLAGS_REG))])]
7524   ""
7525   "")
7527 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7528 ;; Penalize eax case slightly because it results in worse scheduling
7529 ;; of code.
7530 (define_insn "*divmodsi4_nocltd"
7531   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7532         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7533                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7534    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7535         (mod:SI (match_dup 2) (match_dup 3)))
7536    (clobber (reg:CC FLAGS_REG))]
7537   "!optimize_size && !TARGET_USE_CLTD"
7538   "#"
7539   [(set_attr "type" "multi")])
7541 (define_insn "*divmodsi4_cltd"
7542   [(set (match_operand:SI 0 "register_operand" "=a")
7543         (div:SI (match_operand:SI 2 "register_operand" "a")
7544                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7545    (set (match_operand:SI 1 "register_operand" "=&d")
7546         (mod:SI (match_dup 2) (match_dup 3)))
7547    (clobber (reg:CC FLAGS_REG))]
7548   "optimize_size || TARGET_USE_CLTD"
7549   "#"
7550   [(set_attr "type" "multi")])
7552 (define_insn "*divmodsi_noext"
7553   [(set (match_operand:SI 0 "register_operand" "=a")
7554         (div:SI (match_operand:SI 1 "register_operand" "0")
7555                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7556    (set (match_operand:SI 3 "register_operand" "=d")
7557         (mod:SI (match_dup 1) (match_dup 2)))
7558    (use (match_operand:SI 4 "register_operand" "3"))
7559    (clobber (reg:CC FLAGS_REG))]
7560   ""
7561   "idiv{l}\t%2"
7562   [(set_attr "type" "idiv")
7563    (set_attr "mode" "SI")])
7565 (define_split
7566   [(set (match_operand:SI 0 "register_operand" "")
7567         (div:SI (match_operand:SI 1 "register_operand" "")
7568                 (match_operand:SI 2 "nonimmediate_operand" "")))
7569    (set (match_operand:SI 3 "register_operand" "")
7570         (mod:SI (match_dup 1) (match_dup 2)))
7571    (clobber (reg:CC FLAGS_REG))]
7572   "reload_completed"
7573   [(parallel [(set (match_dup 3)
7574                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7575               (clobber (reg:CC FLAGS_REG))])
7576    (parallel [(set (match_dup 0)
7577                    (div:SI (reg:SI 0) (match_dup 2)))
7578               (set (match_dup 3)
7579                    (mod:SI (reg:SI 0) (match_dup 2)))
7580               (use (match_dup 3))
7581               (clobber (reg:CC FLAGS_REG))])]
7583   /* Avoid use of cltd in favor of a mov+shift.  */
7584   if (!TARGET_USE_CLTD && !optimize_size)
7585     {
7586       if (true_regnum (operands[1]))
7587         emit_move_insn (operands[0], operands[1]);
7588       else
7589         emit_move_insn (operands[3], operands[1]);
7590       operands[4] = operands[3];
7591     }
7592   else
7593     {
7594       gcc_assert (!true_regnum (operands[1]));
7595       operands[4] = operands[1];
7596     }
7598 ;; %%% Split me.
7599 (define_insn "divmodhi4"
7600   [(set (match_operand:HI 0 "register_operand" "=a")
7601         (div:HI (match_operand:HI 1 "register_operand" "0")
7602                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7603    (set (match_operand:HI 3 "register_operand" "=&d")
7604         (mod:HI (match_dup 1) (match_dup 2)))
7605    (clobber (reg:CC FLAGS_REG))]
7606   "TARGET_HIMODE_MATH"
7607   "cwtd\;idiv{w}\t%2"
7608   [(set_attr "type" "multi")
7609    (set_attr "length_immediate" "0")
7610    (set_attr "mode" "SI")])
7612 (define_insn "udivmoddi4"
7613   [(set (match_operand:DI 0 "register_operand" "=a")
7614         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7615                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7616    (set (match_operand:DI 3 "register_operand" "=&d")
7617         (umod:DI (match_dup 1) (match_dup 2)))
7618    (clobber (reg:CC FLAGS_REG))]
7619   "TARGET_64BIT"
7620   "xor{q}\t%3, %3\;div{q}\t%2"
7621   [(set_attr "type" "multi")
7622    (set_attr "length_immediate" "0")
7623    (set_attr "mode" "DI")])
7625 (define_insn "*udivmoddi4_noext"
7626   [(set (match_operand:DI 0 "register_operand" "=a")
7627         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7628                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7629    (set (match_operand:DI 3 "register_operand" "=d")
7630         (umod:DI (match_dup 1) (match_dup 2)))
7631    (use (match_dup 3))
7632    (clobber (reg:CC FLAGS_REG))]
7633   "TARGET_64BIT"
7634   "div{q}\t%2"
7635   [(set_attr "type" "idiv")
7636    (set_attr "mode" "DI")])
7638 (define_split
7639   [(set (match_operand:DI 0 "register_operand" "")
7640         (udiv:DI (match_operand:DI 1 "register_operand" "")
7641                  (match_operand:DI 2 "nonimmediate_operand" "")))
7642    (set (match_operand:DI 3 "register_operand" "")
7643         (umod:DI (match_dup 1) (match_dup 2)))
7644    (clobber (reg:CC FLAGS_REG))]
7645   "TARGET_64BIT && reload_completed"
7646   [(set (match_dup 3) (const_int 0))
7647    (parallel [(set (match_dup 0)
7648                    (udiv:DI (match_dup 1) (match_dup 2)))
7649               (set (match_dup 3)
7650                    (umod:DI (match_dup 1) (match_dup 2)))
7651               (use (match_dup 3))
7652               (clobber (reg:CC FLAGS_REG))])]
7653   "")
7655 (define_insn "udivmodsi4"
7656   [(set (match_operand:SI 0 "register_operand" "=a")
7657         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7658                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7659    (set (match_operand:SI 3 "register_operand" "=&d")
7660         (umod:SI (match_dup 1) (match_dup 2)))
7661    (clobber (reg:CC FLAGS_REG))]
7662   ""
7663   "xor{l}\t%3, %3\;div{l}\t%2"
7664   [(set_attr "type" "multi")
7665    (set_attr "length_immediate" "0")
7666    (set_attr "mode" "SI")])
7668 (define_insn "*udivmodsi4_noext"
7669   [(set (match_operand:SI 0 "register_operand" "=a")
7670         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7671                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7672    (set (match_operand:SI 3 "register_operand" "=d")
7673         (umod:SI (match_dup 1) (match_dup 2)))
7674    (use (match_dup 3))
7675    (clobber (reg:CC FLAGS_REG))]
7676   ""
7677   "div{l}\t%2"
7678   [(set_attr "type" "idiv")
7679    (set_attr "mode" "SI")])
7681 (define_split
7682   [(set (match_operand:SI 0 "register_operand" "")
7683         (udiv:SI (match_operand:SI 1 "register_operand" "")
7684                  (match_operand:SI 2 "nonimmediate_operand" "")))
7685    (set (match_operand:SI 3 "register_operand" "")
7686         (umod:SI (match_dup 1) (match_dup 2)))
7687    (clobber (reg:CC FLAGS_REG))]
7688   "reload_completed"
7689   [(set (match_dup 3) (const_int 0))
7690    (parallel [(set (match_dup 0)
7691                    (udiv:SI (match_dup 1) (match_dup 2)))
7692               (set (match_dup 3)
7693                    (umod:SI (match_dup 1) (match_dup 2)))
7694               (use (match_dup 3))
7695               (clobber (reg:CC FLAGS_REG))])]
7696   "")
7698 (define_expand "udivmodhi4"
7699   [(set (match_dup 4) (const_int 0))
7700    (parallel [(set (match_operand:HI 0 "register_operand" "")
7701                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7702                             (match_operand:HI 2 "nonimmediate_operand" "")))
7703               (set (match_operand:HI 3 "register_operand" "")
7704                    (umod:HI (match_dup 1) (match_dup 2)))
7705               (use (match_dup 4))
7706               (clobber (reg:CC FLAGS_REG))])]
7707   "TARGET_HIMODE_MATH"
7708   "operands[4] = gen_reg_rtx (HImode);")
7710 (define_insn "*udivmodhi_noext"
7711   [(set (match_operand:HI 0 "register_operand" "=a")
7712         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7713                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7714    (set (match_operand:HI 3 "register_operand" "=d")
7715         (umod:HI (match_dup 1) (match_dup 2)))
7716    (use (match_operand:HI 4 "register_operand" "3"))
7717    (clobber (reg:CC FLAGS_REG))]
7718   ""
7719   "div{w}\t%2"
7720   [(set_attr "type" "idiv")
7721    (set_attr "mode" "HI")])
7723 ;; We cannot use div/idiv for double division, because it causes
7724 ;; "division by zero" on the overflow and that's not what we expect
7725 ;; from truncate.  Because true (non truncating) double division is
7726 ;; never generated, we can't create this insn anyway.
7728 ;(define_insn ""
7729 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7730 ;       (truncate:SI
7731 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7732 ;                  (zero_extend:DI
7733 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7734 ;   (set (match_operand:SI 3 "register_operand" "=d")
7735 ;       (truncate:SI
7736 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7737 ;   (clobber (reg:CC FLAGS_REG))]
7738 ;  ""
7739 ;  "div{l}\t{%2, %0|%0, %2}"
7740 ;  [(set_attr "type" "idiv")])
7742 ;;- Logical AND instructions
7744 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7745 ;; Note that this excludes ah.
7747 (define_insn "*testdi_1_rex64"
7748   [(set (reg FLAGS_REG)
7749         (compare
7750           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7751                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7752           (const_int 0)))]
7753   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7754    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7755   "@
7756    test{l}\t{%k1, %k0|%k0, %k1}
7757    test{l}\t{%k1, %k0|%k0, %k1}
7758    test{q}\t{%1, %0|%0, %1}
7759    test{q}\t{%1, %0|%0, %1}
7760    test{q}\t{%1, %0|%0, %1}"
7761   [(set_attr "type" "test")
7762    (set_attr "modrm" "0,1,0,1,1")
7763    (set_attr "mode" "SI,SI,DI,DI,DI")
7764    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7766 (define_insn "testsi_1"
7767   [(set (reg FLAGS_REG)
7768         (compare
7769           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7770                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7771           (const_int 0)))]
7772   "ix86_match_ccmode (insn, CCNOmode)
7773    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7774   "test{l}\t{%1, %0|%0, %1}"
7775   [(set_attr "type" "test")
7776    (set_attr "modrm" "0,1,1")
7777    (set_attr "mode" "SI")
7778    (set_attr "pent_pair" "uv,np,uv")])
7780 (define_expand "testsi_ccno_1"
7781   [(set (reg:CCNO FLAGS_REG)
7782         (compare:CCNO
7783           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7784                   (match_operand:SI 1 "nonmemory_operand" ""))
7785           (const_int 0)))]
7786   ""
7787   "")
7789 (define_insn "*testhi_1"
7790   [(set (reg FLAGS_REG)
7791         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7792                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7793                  (const_int 0)))]
7794   "ix86_match_ccmode (insn, CCNOmode)
7795    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7796   "test{w}\t{%1, %0|%0, %1}"
7797   [(set_attr "type" "test")
7798    (set_attr "modrm" "0,1,1")
7799    (set_attr "mode" "HI")
7800    (set_attr "pent_pair" "uv,np,uv")])
7802 (define_expand "testqi_ccz_1"
7803   [(set (reg:CCZ FLAGS_REG)
7804         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7805                              (match_operand:QI 1 "nonmemory_operand" ""))
7806                  (const_int 0)))]
7807   ""
7808   "")
7810 (define_insn "*testqi_1_maybe_si"
7811   [(set (reg FLAGS_REG)
7812         (compare
7813           (and:QI
7814             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7815             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7816           (const_int 0)))]
7817    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7818     && ix86_match_ccmode (insn,
7819                          GET_CODE (operands[1]) == CONST_INT
7820                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7822   if (which_alternative == 3)
7823     {
7824       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7825         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7826       return "test{l}\t{%1, %k0|%k0, %1}";
7827     }
7828   return "test{b}\t{%1, %0|%0, %1}";
7830   [(set_attr "type" "test")
7831    (set_attr "modrm" "0,1,1,1")
7832    (set_attr "mode" "QI,QI,QI,SI")
7833    (set_attr "pent_pair" "uv,np,uv,np")])
7835 (define_insn "*testqi_1"
7836   [(set (reg FLAGS_REG)
7837         (compare
7838           (and:QI
7839             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7840             (match_operand:QI 1 "general_operand" "n,n,qn"))
7841           (const_int 0)))]
7842   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7843    && ix86_match_ccmode (insn, CCNOmode)"
7844   "test{b}\t{%1, %0|%0, %1}"
7845   [(set_attr "type" "test")
7846    (set_attr "modrm" "0,1,1")
7847    (set_attr "mode" "QI")
7848    (set_attr "pent_pair" "uv,np,uv")])
7850 (define_expand "testqi_ext_ccno_0"
7851   [(set (reg:CCNO FLAGS_REG)
7852         (compare:CCNO
7853           (and:SI
7854             (zero_extract:SI
7855               (match_operand 0 "ext_register_operand" "")
7856               (const_int 8)
7857               (const_int 8))
7858             (match_operand 1 "const_int_operand" ""))
7859           (const_int 0)))]
7860   ""
7861   "")
7863 (define_insn "*testqi_ext_0"
7864   [(set (reg FLAGS_REG)
7865         (compare
7866           (and:SI
7867             (zero_extract:SI
7868               (match_operand 0 "ext_register_operand" "Q")
7869               (const_int 8)
7870               (const_int 8))
7871             (match_operand 1 "const_int_operand" "n"))
7872           (const_int 0)))]
7873   "ix86_match_ccmode (insn, CCNOmode)"
7874   "test{b}\t{%1, %h0|%h0, %1}"
7875   [(set_attr "type" "test")
7876    (set_attr "mode" "QI")
7877    (set_attr "length_immediate" "1")
7878    (set_attr "pent_pair" "np")])
7880 (define_insn "*testqi_ext_1"
7881   [(set (reg FLAGS_REG)
7882         (compare
7883           (and:SI
7884             (zero_extract:SI
7885               (match_operand 0 "ext_register_operand" "Q")
7886               (const_int 8)
7887               (const_int 8))
7888             (zero_extend:SI
7889               (match_operand:QI 1 "general_operand" "Qm")))
7890           (const_int 0)))]
7891   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7892    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7893   "test{b}\t{%1, %h0|%h0, %1}"
7894   [(set_attr "type" "test")
7895    (set_attr "mode" "QI")])
7897 (define_insn "*testqi_ext_1_rex64"
7898   [(set (reg FLAGS_REG)
7899         (compare
7900           (and:SI
7901             (zero_extract:SI
7902               (match_operand 0 "ext_register_operand" "Q")
7903               (const_int 8)
7904               (const_int 8))
7905             (zero_extend:SI
7906               (match_operand:QI 1 "register_operand" "Q")))
7907           (const_int 0)))]
7908   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7909   "test{b}\t{%1, %h0|%h0, %1}"
7910   [(set_attr "type" "test")
7911    (set_attr "mode" "QI")])
7913 (define_insn "*testqi_ext_2"
7914   [(set (reg FLAGS_REG)
7915         (compare
7916           (and:SI
7917             (zero_extract:SI
7918               (match_operand 0 "ext_register_operand" "Q")
7919               (const_int 8)
7920               (const_int 8))
7921             (zero_extract:SI
7922               (match_operand 1 "ext_register_operand" "Q")
7923               (const_int 8)
7924               (const_int 8)))
7925           (const_int 0)))]
7926   "ix86_match_ccmode (insn, CCNOmode)"
7927   "test{b}\t{%h1, %h0|%h0, %h1}"
7928   [(set_attr "type" "test")
7929    (set_attr "mode" "QI")])
7931 ;; Combine likes to form bit extractions for some tests.  Humor it.
7932 (define_insn "*testqi_ext_3"
7933   [(set (reg FLAGS_REG)
7934         (compare (zero_extract:SI
7935                    (match_operand 0 "nonimmediate_operand" "rm")
7936                    (match_operand:SI 1 "const_int_operand" "")
7937                    (match_operand:SI 2 "const_int_operand" ""))
7938                  (const_int 0)))]
7939   "ix86_match_ccmode (insn, CCNOmode)
7940    && INTVAL (operands[1]) > 0
7941    && INTVAL (operands[2]) >= 0
7942    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7943    && (GET_MODE (operands[0]) == SImode
7944        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7945        || GET_MODE (operands[0]) == HImode
7946        || GET_MODE (operands[0]) == QImode)"
7947   "#")
7949 (define_insn "*testqi_ext_3_rex64"
7950   [(set (reg FLAGS_REG)
7951         (compare (zero_extract:DI
7952                    (match_operand 0 "nonimmediate_operand" "rm")
7953                    (match_operand:DI 1 "const_int_operand" "")
7954                    (match_operand:DI 2 "const_int_operand" ""))
7955                  (const_int 0)))]
7956   "TARGET_64BIT
7957    && ix86_match_ccmode (insn, CCNOmode)
7958    && INTVAL (operands[1]) > 0
7959    && INTVAL (operands[2]) >= 0
7960    /* Ensure that resulting mask is zero or sign extended operand.  */
7961    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7962        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7963            && INTVAL (operands[1]) > 32))
7964    && (GET_MODE (operands[0]) == SImode
7965        || GET_MODE (operands[0]) == DImode
7966        || GET_MODE (operands[0]) == HImode
7967        || GET_MODE (operands[0]) == QImode)"
7968   "#")
7970 (define_split
7971   [(set (match_operand 0 "flags_reg_operand" "")
7972         (match_operator 1 "compare_operator"
7973           [(zero_extract
7974              (match_operand 2 "nonimmediate_operand" "")
7975              (match_operand 3 "const_int_operand" "")
7976              (match_operand 4 "const_int_operand" ""))
7977            (const_int 0)]))]
7978   "ix86_match_ccmode (insn, CCNOmode)"
7979   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7981   rtx val = operands[2];
7982   HOST_WIDE_INT len = INTVAL (operands[3]);
7983   HOST_WIDE_INT pos = INTVAL (operands[4]);
7984   HOST_WIDE_INT mask;
7985   enum machine_mode mode, submode;
7987   mode = GET_MODE (val);
7988   if (GET_CODE (val) == MEM)
7989     {
7990       /* ??? Combine likes to put non-volatile mem extractions in QImode
7991          no matter the size of the test.  So find a mode that works.  */
7992       if (! MEM_VOLATILE_P (val))
7993         {
7994           mode = smallest_mode_for_size (pos + len, MODE_INT);
7995           val = adjust_address (val, mode, 0);
7996         }
7997     }
7998   else if (GET_CODE (val) == SUBREG
7999            && (submode = GET_MODE (SUBREG_REG (val)),
8000                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8001            && pos + len <= GET_MODE_BITSIZE (submode))
8002     {
8003       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8004       mode = submode;
8005       val = SUBREG_REG (val);
8006     }
8007   else if (mode == HImode && pos + len <= 8)
8008     {
8009       /* Small HImode tests can be converted to QImode.  */
8010       mode = QImode;
8011       val = gen_lowpart (QImode, val);
8012     }
8014   if (len == HOST_BITS_PER_WIDE_INT)
8015     mask = -1;
8016   else
8017     mask = ((HOST_WIDE_INT)1 << len) - 1;
8018   mask <<= pos;
8020   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8023 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8024 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8025 ;; this is relatively important trick.
8026 ;; Do the conversion only post-reload to avoid limiting of the register class
8027 ;; to QI regs.
8028 (define_split
8029   [(set (match_operand 0 "flags_reg_operand" "")
8030         (match_operator 1 "compare_operator"
8031           [(and (match_operand 2 "register_operand" "")
8032                 (match_operand 3 "const_int_operand" ""))
8033            (const_int 0)]))]
8034    "reload_completed
8035     && QI_REG_P (operands[2])
8036     && GET_MODE (operands[2]) != QImode
8037     && ((ix86_match_ccmode (insn, CCZmode)
8038          && !(INTVAL (operands[3]) & ~(255 << 8)))
8039         || (ix86_match_ccmode (insn, CCNOmode)
8040             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8041   [(set (match_dup 0)
8042         (match_op_dup 1
8043           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8044                    (match_dup 3))
8045            (const_int 0)]))]
8046   "operands[2] = gen_lowpart (SImode, operands[2]);
8047    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8049 (define_split
8050   [(set (match_operand 0 "flags_reg_operand" "")
8051         (match_operator 1 "compare_operator"
8052           [(and (match_operand 2 "nonimmediate_operand" "")
8053                 (match_operand 3 "const_int_operand" ""))
8054            (const_int 0)]))]
8055    "reload_completed
8056     && GET_MODE (operands[2]) != QImode
8057     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8058     && ((ix86_match_ccmode (insn, CCZmode)
8059          && !(INTVAL (operands[3]) & ~255))
8060         || (ix86_match_ccmode (insn, CCNOmode)
8061             && !(INTVAL (operands[3]) & ~127)))"
8062   [(set (match_dup 0)
8063         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8064                          (const_int 0)]))]
8065   "operands[2] = gen_lowpart (QImode, operands[2]);
8066    operands[3] = gen_lowpart (QImode, operands[3]);")
8069 ;; %%% This used to optimize known byte-wide and operations to memory,
8070 ;; and sometimes to QImode registers.  If this is considered useful,
8071 ;; it should be done with splitters.
8073 (define_expand "anddi3"
8074   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8075         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8076                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8077    (clobber (reg:CC FLAGS_REG))]
8078   "TARGET_64BIT"
8079   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8081 (define_insn "*anddi_1_rex64"
8082   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8083         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8084                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8085    (clobber (reg:CC FLAGS_REG))]
8086   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8088   switch (get_attr_type (insn))
8089     {
8090     case TYPE_IMOVX:
8091       {
8092         enum machine_mode mode;
8094         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8095         if (INTVAL (operands[2]) == 0xff)
8096           mode = QImode;
8097         else
8098           {
8099             gcc_assert (INTVAL (operands[2]) == 0xffff);
8100             mode = HImode;
8101           }
8103         operands[1] = gen_lowpart (mode, operands[1]);
8104         if (mode == QImode)
8105           return "movz{bq|x}\t{%1,%0|%0, %1}";
8106         else
8107           return "movz{wq|x}\t{%1,%0|%0, %1}";
8108       }
8110     default:
8111       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8112       if (get_attr_mode (insn) == MODE_SI)
8113         return "and{l}\t{%k2, %k0|%k0, %k2}";
8114       else
8115         return "and{q}\t{%2, %0|%0, %2}";
8116     }
8118   [(set_attr "type" "alu,alu,alu,imovx")
8119    (set_attr "length_immediate" "*,*,*,0")
8120    (set_attr "mode" "SI,DI,DI,DI")])
8122 (define_insn "*anddi_2"
8123   [(set (reg FLAGS_REG)
8124         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8125                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8126                  (const_int 0)))
8127    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8128         (and:DI (match_dup 1) (match_dup 2)))]
8129   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8130    && ix86_binary_operator_ok (AND, DImode, operands)"
8131   "@
8132    and{l}\t{%k2, %k0|%k0, %k2}
8133    and{q}\t{%2, %0|%0, %2}
8134    and{q}\t{%2, %0|%0, %2}"
8135   [(set_attr "type" "alu")
8136    (set_attr "mode" "SI,DI,DI")])
8138 (define_expand "andsi3"
8139   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8140         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8141                 (match_operand:SI 2 "general_operand" "")))
8142    (clobber (reg:CC FLAGS_REG))]
8143   ""
8144   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8146 (define_insn "*andsi_1"
8147   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8148         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8149                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8150    (clobber (reg:CC FLAGS_REG))]
8151   "ix86_binary_operator_ok (AND, SImode, operands)"
8153   switch (get_attr_type (insn))
8154     {
8155     case TYPE_IMOVX:
8156       {
8157         enum machine_mode mode;
8159         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8160         if (INTVAL (operands[2]) == 0xff)
8161           mode = QImode;
8162         else
8163           {
8164             gcc_assert (INTVAL (operands[2]) == 0xffff);
8165             mode = HImode;
8166           }
8168         operands[1] = gen_lowpart (mode, operands[1]);
8169         if (mode == QImode)
8170           return "movz{bl|x}\t{%1,%0|%0, %1}";
8171         else
8172           return "movz{wl|x}\t{%1,%0|%0, %1}";
8173       }
8175     default:
8176       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8177       return "and{l}\t{%2, %0|%0, %2}";
8178     }
8180   [(set_attr "type" "alu,alu,imovx")
8181    (set_attr "length_immediate" "*,*,0")
8182    (set_attr "mode" "SI")])
8184 (define_split
8185   [(set (match_operand 0 "register_operand" "")
8186         (and (match_dup 0)
8187              (const_int -65536)))
8188    (clobber (reg:CC FLAGS_REG))]
8189   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8190   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8191   "operands[1] = gen_lowpart (HImode, operands[0]);")
8193 (define_split
8194   [(set (match_operand 0 "ext_register_operand" "")
8195         (and (match_dup 0)
8196              (const_int -256)))
8197    (clobber (reg:CC FLAGS_REG))]
8198   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8199   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8200   "operands[1] = gen_lowpart (QImode, operands[0]);")
8202 (define_split
8203   [(set (match_operand 0 "ext_register_operand" "")
8204         (and (match_dup 0)
8205              (const_int -65281)))
8206    (clobber (reg:CC FLAGS_REG))]
8207   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8208   [(parallel [(set (zero_extract:SI (match_dup 0)
8209                                     (const_int 8)
8210                                     (const_int 8))
8211                    (xor:SI
8212                      (zero_extract:SI (match_dup 0)
8213                                       (const_int 8)
8214                                       (const_int 8))
8215                      (zero_extract:SI (match_dup 0)
8216                                       (const_int 8)
8217                                       (const_int 8))))
8218               (clobber (reg:CC FLAGS_REG))])]
8219   "operands[0] = gen_lowpart (SImode, operands[0]);")
8221 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8222 (define_insn "*andsi_1_zext"
8223   [(set (match_operand:DI 0 "register_operand" "=r")
8224         (zero_extend:DI
8225           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8226                   (match_operand:SI 2 "general_operand" "rim"))))
8227    (clobber (reg:CC FLAGS_REG))]
8228   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8229   "and{l}\t{%2, %k0|%k0, %2}"
8230   [(set_attr "type" "alu")
8231    (set_attr "mode" "SI")])
8233 (define_insn "*andsi_2"
8234   [(set (reg FLAGS_REG)
8235         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8236                          (match_operand:SI 2 "general_operand" "rim,ri"))
8237                  (const_int 0)))
8238    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8239         (and:SI (match_dup 1) (match_dup 2)))]
8240   "ix86_match_ccmode (insn, CCNOmode)
8241    && ix86_binary_operator_ok (AND, SImode, operands)"
8242   "and{l}\t{%2, %0|%0, %2}"
8243   [(set_attr "type" "alu")
8244    (set_attr "mode" "SI")])
8246 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8247 (define_insn "*andsi_2_zext"
8248   [(set (reg FLAGS_REG)
8249         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8250                          (match_operand:SI 2 "general_operand" "rim"))
8251                  (const_int 0)))
8252    (set (match_operand:DI 0 "register_operand" "=r")
8253         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8254   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8255    && ix86_binary_operator_ok (AND, SImode, operands)"
8256   "and{l}\t{%2, %k0|%k0, %2}"
8257   [(set_attr "type" "alu")
8258    (set_attr "mode" "SI")])
8260 (define_expand "andhi3"
8261   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8262         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8263                 (match_operand:HI 2 "general_operand" "")))
8264    (clobber (reg:CC FLAGS_REG))]
8265   "TARGET_HIMODE_MATH"
8266   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8268 (define_insn "*andhi_1"
8269   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8270         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8271                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8272    (clobber (reg:CC FLAGS_REG))]
8273   "ix86_binary_operator_ok (AND, HImode, operands)"
8275   switch (get_attr_type (insn))
8276     {
8277     case TYPE_IMOVX:
8278       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8279       gcc_assert (INTVAL (operands[2]) == 0xff);
8280       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8282     default:
8283       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8285       return "and{w}\t{%2, %0|%0, %2}";
8286     }
8288   [(set_attr "type" "alu,alu,imovx")
8289    (set_attr "length_immediate" "*,*,0")
8290    (set_attr "mode" "HI,HI,SI")])
8292 (define_insn "*andhi_2"
8293   [(set (reg FLAGS_REG)
8294         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8295                          (match_operand:HI 2 "general_operand" "rim,ri"))
8296                  (const_int 0)))
8297    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8298         (and:HI (match_dup 1) (match_dup 2)))]
8299   "ix86_match_ccmode (insn, CCNOmode)
8300    && ix86_binary_operator_ok (AND, HImode, operands)"
8301   "and{w}\t{%2, %0|%0, %2}"
8302   [(set_attr "type" "alu")
8303    (set_attr "mode" "HI")])
8305 (define_expand "andqi3"
8306   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8307         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8308                 (match_operand:QI 2 "general_operand" "")))
8309    (clobber (reg:CC FLAGS_REG))]
8310   "TARGET_QIMODE_MATH"
8311   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8313 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8314 (define_insn "*andqi_1"
8315   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8316         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8317                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8318    (clobber (reg:CC FLAGS_REG))]
8319   "ix86_binary_operator_ok (AND, QImode, operands)"
8320   "@
8321    and{b}\t{%2, %0|%0, %2}
8322    and{b}\t{%2, %0|%0, %2}
8323    and{l}\t{%k2, %k0|%k0, %k2}"
8324   [(set_attr "type" "alu")
8325    (set_attr "mode" "QI,QI,SI")])
8327 (define_insn "*andqi_1_slp"
8328   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8329         (and:QI (match_dup 0)
8330                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8331    (clobber (reg:CC FLAGS_REG))]
8332   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8333    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8334   "and{b}\t{%1, %0|%0, %1}"
8335   [(set_attr "type" "alu1")
8336    (set_attr "mode" "QI")])
8338 (define_insn "*andqi_2_maybe_si"
8339   [(set (reg FLAGS_REG)
8340         (compare (and:QI
8341                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8342                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8343                  (const_int 0)))
8344    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8345         (and:QI (match_dup 1) (match_dup 2)))]
8346   "ix86_binary_operator_ok (AND, QImode, operands)
8347    && ix86_match_ccmode (insn,
8348                          GET_CODE (operands[2]) == CONST_INT
8349                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8351   if (which_alternative == 2)
8352     {
8353       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8354         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8355       return "and{l}\t{%2, %k0|%k0, %2}";
8356     }
8357   return "and{b}\t{%2, %0|%0, %2}";
8359   [(set_attr "type" "alu")
8360    (set_attr "mode" "QI,QI,SI")])
8362 (define_insn "*andqi_2"
8363   [(set (reg FLAGS_REG)
8364         (compare (and:QI
8365                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8366                    (match_operand:QI 2 "general_operand" "qim,qi"))
8367                  (const_int 0)))
8368    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8369         (and:QI (match_dup 1) (match_dup 2)))]
8370   "ix86_match_ccmode (insn, CCNOmode)
8371    && ix86_binary_operator_ok (AND, QImode, operands)"
8372   "and{b}\t{%2, %0|%0, %2}"
8373   [(set_attr "type" "alu")
8374    (set_attr "mode" "QI")])
8376 (define_insn "*andqi_2_slp"
8377   [(set (reg FLAGS_REG)
8378         (compare (and:QI
8379                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8380                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8381                  (const_int 0)))
8382    (set (strict_low_part (match_dup 0))
8383         (and:QI (match_dup 0) (match_dup 1)))]
8384   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8385    && ix86_match_ccmode (insn, CCNOmode)
8386    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8387   "and{b}\t{%1, %0|%0, %1}"
8388   [(set_attr "type" "alu1")
8389    (set_attr "mode" "QI")])
8391 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8392 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8393 ;; for a QImode operand, which of course failed.
8395 (define_insn "andqi_ext_0"
8396   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8397                          (const_int 8)
8398                          (const_int 8))
8399         (and:SI
8400           (zero_extract:SI
8401             (match_operand 1 "ext_register_operand" "0")
8402             (const_int 8)
8403             (const_int 8))
8404           (match_operand 2 "const_int_operand" "n")))
8405    (clobber (reg:CC FLAGS_REG))]
8406   ""
8407   "and{b}\t{%2, %h0|%h0, %2}"
8408   [(set_attr "type" "alu")
8409    (set_attr "length_immediate" "1")
8410    (set_attr "mode" "QI")])
8412 ;; Generated by peephole translating test to and.  This shows up
8413 ;; often in fp comparisons.
8415 (define_insn "*andqi_ext_0_cc"
8416   [(set (reg FLAGS_REG)
8417         (compare
8418           (and:SI
8419             (zero_extract:SI
8420               (match_operand 1 "ext_register_operand" "0")
8421               (const_int 8)
8422               (const_int 8))
8423             (match_operand 2 "const_int_operand" "n"))
8424           (const_int 0)))
8425    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8426                          (const_int 8)
8427                          (const_int 8))
8428         (and:SI
8429           (zero_extract:SI
8430             (match_dup 1)
8431             (const_int 8)
8432             (const_int 8))
8433           (match_dup 2)))]
8434   "ix86_match_ccmode (insn, CCNOmode)"
8435   "and{b}\t{%2, %h0|%h0, %2}"
8436   [(set_attr "type" "alu")
8437    (set_attr "length_immediate" "1")
8438    (set_attr "mode" "QI")])
8440 (define_insn "*andqi_ext_1"
8441   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8442                          (const_int 8)
8443                          (const_int 8))
8444         (and:SI
8445           (zero_extract:SI
8446             (match_operand 1 "ext_register_operand" "0")
8447             (const_int 8)
8448             (const_int 8))
8449           (zero_extend:SI
8450             (match_operand:QI 2 "general_operand" "Qm"))))
8451    (clobber (reg:CC FLAGS_REG))]
8452   "!TARGET_64BIT"
8453   "and{b}\t{%2, %h0|%h0, %2}"
8454   [(set_attr "type" "alu")
8455    (set_attr "length_immediate" "0")
8456    (set_attr "mode" "QI")])
8458 (define_insn "*andqi_ext_1_rex64"
8459   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8460                          (const_int 8)
8461                          (const_int 8))
8462         (and:SI
8463           (zero_extract:SI
8464             (match_operand 1 "ext_register_operand" "0")
8465             (const_int 8)
8466             (const_int 8))
8467           (zero_extend:SI
8468             (match_operand 2 "ext_register_operand" "Q"))))
8469    (clobber (reg:CC FLAGS_REG))]
8470   "TARGET_64BIT"
8471   "and{b}\t{%2, %h0|%h0, %2}"
8472   [(set_attr "type" "alu")
8473    (set_attr "length_immediate" "0")
8474    (set_attr "mode" "QI")])
8476 (define_insn "*andqi_ext_2"
8477   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8478                          (const_int 8)
8479                          (const_int 8))
8480         (and:SI
8481           (zero_extract:SI
8482             (match_operand 1 "ext_register_operand" "%0")
8483             (const_int 8)
8484             (const_int 8))
8485           (zero_extract:SI
8486             (match_operand 2 "ext_register_operand" "Q")
8487             (const_int 8)
8488             (const_int 8))))
8489    (clobber (reg:CC FLAGS_REG))]
8490   ""
8491   "and{b}\t{%h2, %h0|%h0, %h2}"
8492   [(set_attr "type" "alu")
8493    (set_attr "length_immediate" "0")
8494    (set_attr "mode" "QI")])
8496 ;; Convert wide AND instructions with immediate operand to shorter QImode
8497 ;; equivalents when possible.
8498 ;; Don't do the splitting with memory operands, since it introduces risk
8499 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8500 ;; for size, but that can (should?) be handled by generic code instead.
8501 (define_split
8502   [(set (match_operand 0 "register_operand" "")
8503         (and (match_operand 1 "register_operand" "")
8504              (match_operand 2 "const_int_operand" "")))
8505    (clobber (reg:CC FLAGS_REG))]
8506    "reload_completed
8507     && QI_REG_P (operands[0])
8508     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8509     && !(~INTVAL (operands[2]) & ~(255 << 8))
8510     && GET_MODE (operands[0]) != QImode"
8511   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8512                    (and:SI (zero_extract:SI (match_dup 1)
8513                                             (const_int 8) (const_int 8))
8514                            (match_dup 2)))
8515               (clobber (reg:CC FLAGS_REG))])]
8516   "operands[0] = gen_lowpart (SImode, operands[0]);
8517    operands[1] = gen_lowpart (SImode, operands[1]);
8518    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8520 ;; Since AND can be encoded with sign extended immediate, this is only
8521 ;; profitable when 7th bit is not set.
8522 (define_split
8523   [(set (match_operand 0 "register_operand" "")
8524         (and (match_operand 1 "general_operand" "")
8525              (match_operand 2 "const_int_operand" "")))
8526    (clobber (reg:CC FLAGS_REG))]
8527    "reload_completed
8528     && ANY_QI_REG_P (operands[0])
8529     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8530     && !(~INTVAL (operands[2]) & ~255)
8531     && !(INTVAL (operands[2]) & 128)
8532     && GET_MODE (operands[0]) != QImode"
8533   [(parallel [(set (strict_low_part (match_dup 0))
8534                    (and:QI (match_dup 1)
8535                            (match_dup 2)))
8536               (clobber (reg:CC FLAGS_REG))])]
8537   "operands[0] = gen_lowpart (QImode, operands[0]);
8538    operands[1] = gen_lowpart (QImode, operands[1]);
8539    operands[2] = gen_lowpart (QImode, operands[2]);")
8541 ;; Logical inclusive OR instructions
8543 ;; %%% This used to optimize known byte-wide and operations to memory.
8544 ;; If this is considered useful, it should be done with splitters.
8546 (define_expand "iordi3"
8547   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8548         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8549                 (match_operand:DI 2 "x86_64_general_operand" "")))
8550    (clobber (reg:CC FLAGS_REG))]
8551   "TARGET_64BIT"
8552   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8554 (define_insn "*iordi_1_rex64"
8555   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8556         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8557                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8558    (clobber (reg:CC FLAGS_REG))]
8559   "TARGET_64BIT
8560    && ix86_binary_operator_ok (IOR, DImode, operands)"
8561   "or{q}\t{%2, %0|%0, %2}"
8562   [(set_attr "type" "alu")
8563    (set_attr "mode" "DI")])
8565 (define_insn "*iordi_2_rex64"
8566   [(set (reg FLAGS_REG)
8567         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8568                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8569                  (const_int 0)))
8570    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8571         (ior:DI (match_dup 1) (match_dup 2)))]
8572   "TARGET_64BIT
8573    && ix86_match_ccmode (insn, CCNOmode)
8574    && ix86_binary_operator_ok (IOR, DImode, operands)"
8575   "or{q}\t{%2, %0|%0, %2}"
8576   [(set_attr "type" "alu")
8577    (set_attr "mode" "DI")])
8579 (define_insn "*iordi_3_rex64"
8580   [(set (reg FLAGS_REG)
8581         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8582                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8583                  (const_int 0)))
8584    (clobber (match_scratch:DI 0 "=r"))]
8585   "TARGET_64BIT
8586    && ix86_match_ccmode (insn, CCNOmode)
8587    && ix86_binary_operator_ok (IOR, DImode, operands)"
8588   "or{q}\t{%2, %0|%0, %2}"
8589   [(set_attr "type" "alu")
8590    (set_attr "mode" "DI")])
8593 (define_expand "iorsi3"
8594   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8595         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8596                 (match_operand:SI 2 "general_operand" "")))
8597    (clobber (reg:CC FLAGS_REG))]
8598   ""
8599   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8601 (define_insn "*iorsi_1"
8602   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8603         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8604                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8605    (clobber (reg:CC FLAGS_REG))]
8606   "ix86_binary_operator_ok (IOR, SImode, operands)"
8607   "or{l}\t{%2, %0|%0, %2}"
8608   [(set_attr "type" "alu")
8609    (set_attr "mode" "SI")])
8611 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8612 (define_insn "*iorsi_1_zext"
8613   [(set (match_operand:DI 0 "register_operand" "=rm")
8614         (zero_extend:DI
8615           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8616                   (match_operand:SI 2 "general_operand" "rim"))))
8617    (clobber (reg:CC FLAGS_REG))]
8618   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8619   "or{l}\t{%2, %k0|%k0, %2}"
8620   [(set_attr "type" "alu")
8621    (set_attr "mode" "SI")])
8623 (define_insn "*iorsi_1_zext_imm"
8624   [(set (match_operand:DI 0 "register_operand" "=rm")
8625         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8626                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8627    (clobber (reg:CC FLAGS_REG))]
8628   "TARGET_64BIT"
8629   "or{l}\t{%2, %k0|%k0, %2}"
8630   [(set_attr "type" "alu")
8631    (set_attr "mode" "SI")])
8633 (define_insn "*iorsi_2"
8634   [(set (reg FLAGS_REG)
8635         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8636                          (match_operand:SI 2 "general_operand" "rim,ri"))
8637                  (const_int 0)))
8638    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8639         (ior:SI (match_dup 1) (match_dup 2)))]
8640   "ix86_match_ccmode (insn, CCNOmode)
8641    && ix86_binary_operator_ok (IOR, SImode, operands)"
8642   "or{l}\t{%2, %0|%0, %2}"
8643   [(set_attr "type" "alu")
8644    (set_attr "mode" "SI")])
8646 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8647 ;; ??? Special case for immediate operand is missing - it is tricky.
8648 (define_insn "*iorsi_2_zext"
8649   [(set (reg FLAGS_REG)
8650         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8651                          (match_operand:SI 2 "general_operand" "rim"))
8652                  (const_int 0)))
8653    (set (match_operand:DI 0 "register_operand" "=r")
8654         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8655   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8656    && ix86_binary_operator_ok (IOR, SImode, operands)"
8657   "or{l}\t{%2, %k0|%k0, %2}"
8658   [(set_attr "type" "alu")
8659    (set_attr "mode" "SI")])
8661 (define_insn "*iorsi_2_zext_imm"
8662   [(set (reg FLAGS_REG)
8663         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8664                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8665                  (const_int 0)))
8666    (set (match_operand:DI 0 "register_operand" "=r")
8667         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8668   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8669    && ix86_binary_operator_ok (IOR, SImode, operands)"
8670   "or{l}\t{%2, %k0|%k0, %2}"
8671   [(set_attr "type" "alu")
8672    (set_attr "mode" "SI")])
8674 (define_insn "*iorsi_3"
8675   [(set (reg FLAGS_REG)
8676         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8677                          (match_operand:SI 2 "general_operand" "rim"))
8678                  (const_int 0)))
8679    (clobber (match_scratch:SI 0 "=r"))]
8680   "ix86_match_ccmode (insn, CCNOmode)
8681    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8682   "or{l}\t{%2, %0|%0, %2}"
8683   [(set_attr "type" "alu")
8684    (set_attr "mode" "SI")])
8686 (define_expand "iorhi3"
8687   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8688         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8689                 (match_operand:HI 2 "general_operand" "")))
8690    (clobber (reg:CC FLAGS_REG))]
8691   "TARGET_HIMODE_MATH"
8692   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8694 (define_insn "*iorhi_1"
8695   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8696         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8697                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8698    (clobber (reg:CC FLAGS_REG))]
8699   "ix86_binary_operator_ok (IOR, HImode, operands)"
8700   "or{w}\t{%2, %0|%0, %2}"
8701   [(set_attr "type" "alu")
8702    (set_attr "mode" "HI")])
8704 (define_insn "*iorhi_2"
8705   [(set (reg FLAGS_REG)
8706         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8707                          (match_operand:HI 2 "general_operand" "rim,ri"))
8708                  (const_int 0)))
8709    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8710         (ior:HI (match_dup 1) (match_dup 2)))]
8711   "ix86_match_ccmode (insn, CCNOmode)
8712    && ix86_binary_operator_ok (IOR, HImode, operands)"
8713   "or{w}\t{%2, %0|%0, %2}"
8714   [(set_attr "type" "alu")
8715    (set_attr "mode" "HI")])
8717 (define_insn "*iorhi_3"
8718   [(set (reg FLAGS_REG)
8719         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8720                          (match_operand:HI 2 "general_operand" "rim"))
8721                  (const_int 0)))
8722    (clobber (match_scratch:HI 0 "=r"))]
8723   "ix86_match_ccmode (insn, CCNOmode)
8724    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8725   "or{w}\t{%2, %0|%0, %2}"
8726   [(set_attr "type" "alu")
8727    (set_attr "mode" "HI")])
8729 (define_expand "iorqi3"
8730   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8731         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8732                 (match_operand:QI 2 "general_operand" "")))
8733    (clobber (reg:CC FLAGS_REG))]
8734   "TARGET_QIMODE_MATH"
8735   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8737 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8738 (define_insn "*iorqi_1"
8739   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8740         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8741                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8742    (clobber (reg:CC FLAGS_REG))]
8743   "ix86_binary_operator_ok (IOR, QImode, operands)"
8744   "@
8745    or{b}\t{%2, %0|%0, %2}
8746    or{b}\t{%2, %0|%0, %2}
8747    or{l}\t{%k2, %k0|%k0, %k2}"
8748   [(set_attr "type" "alu")
8749    (set_attr "mode" "QI,QI,SI")])
8751 (define_insn "*iorqi_1_slp"
8752   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8753         (ior:QI (match_dup 0)
8754                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8755    (clobber (reg:CC FLAGS_REG))]
8756   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8757    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8758   "or{b}\t{%1, %0|%0, %1}"
8759   [(set_attr "type" "alu1")
8760    (set_attr "mode" "QI")])
8762 (define_insn "*iorqi_2"
8763   [(set (reg FLAGS_REG)
8764         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8765                          (match_operand:QI 2 "general_operand" "qim,qi"))
8766                  (const_int 0)))
8767    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8768         (ior:QI (match_dup 1) (match_dup 2)))]
8769   "ix86_match_ccmode (insn, CCNOmode)
8770    && ix86_binary_operator_ok (IOR, QImode, operands)"
8771   "or{b}\t{%2, %0|%0, %2}"
8772   [(set_attr "type" "alu")
8773    (set_attr "mode" "QI")])
8775 (define_insn "*iorqi_2_slp"
8776   [(set (reg FLAGS_REG)
8777         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8778                          (match_operand:QI 1 "general_operand" "qim,qi"))
8779                  (const_int 0)))
8780    (set (strict_low_part (match_dup 0))
8781         (ior:QI (match_dup 0) (match_dup 1)))]
8782   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8783    && ix86_match_ccmode (insn, CCNOmode)
8784    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8785   "or{b}\t{%1, %0|%0, %1}"
8786   [(set_attr "type" "alu1")
8787    (set_attr "mode" "QI")])
8789 (define_insn "*iorqi_3"
8790   [(set (reg FLAGS_REG)
8791         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8792                          (match_operand:QI 2 "general_operand" "qim"))
8793                  (const_int 0)))
8794    (clobber (match_scratch:QI 0 "=q"))]
8795   "ix86_match_ccmode (insn, CCNOmode)
8796    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8797   "or{b}\t{%2, %0|%0, %2}"
8798   [(set_attr "type" "alu")
8799    (set_attr "mode" "QI")])
8801 (define_insn "iorqi_ext_0"
8802   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8803                          (const_int 8)
8804                          (const_int 8))
8805         (ior:SI
8806           (zero_extract:SI
8807             (match_operand 1 "ext_register_operand" "0")
8808             (const_int 8)
8809             (const_int 8))
8810           (match_operand 2 "const_int_operand" "n")))
8811    (clobber (reg:CC FLAGS_REG))]
8812   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8813   "or{b}\t{%2, %h0|%h0, %2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "length_immediate" "1")
8816    (set_attr "mode" "QI")])
8818 (define_insn "*iorqi_ext_1"
8819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8820                          (const_int 8)
8821                          (const_int 8))
8822         (ior:SI
8823           (zero_extract:SI
8824             (match_operand 1 "ext_register_operand" "0")
8825             (const_int 8)
8826             (const_int 8))
8827           (zero_extend:SI
8828             (match_operand:QI 2 "general_operand" "Qm"))))
8829    (clobber (reg:CC FLAGS_REG))]
8830   "!TARGET_64BIT
8831    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8832   "or{b}\t{%2, %h0|%h0, %2}"
8833   [(set_attr "type" "alu")
8834    (set_attr "length_immediate" "0")
8835    (set_attr "mode" "QI")])
8837 (define_insn "*iorqi_ext_1_rex64"
8838   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8839                          (const_int 8)
8840                          (const_int 8))
8841         (ior:SI
8842           (zero_extract:SI
8843             (match_operand 1 "ext_register_operand" "0")
8844             (const_int 8)
8845             (const_int 8))
8846           (zero_extend:SI
8847             (match_operand 2 "ext_register_operand" "Q"))))
8848    (clobber (reg:CC FLAGS_REG))]
8849   "TARGET_64BIT
8850    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8851   "or{b}\t{%2, %h0|%h0, %2}"
8852   [(set_attr "type" "alu")
8853    (set_attr "length_immediate" "0")
8854    (set_attr "mode" "QI")])
8856 (define_insn "*iorqi_ext_2"
8857   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8858                          (const_int 8)
8859                          (const_int 8))
8860         (ior:SI
8861           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8862                            (const_int 8)
8863                            (const_int 8))
8864           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8865                            (const_int 8)
8866                            (const_int 8))))
8867    (clobber (reg:CC FLAGS_REG))]
8868   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8869   "ior{b}\t{%h2, %h0|%h0, %h2}"
8870   [(set_attr "type" "alu")
8871    (set_attr "length_immediate" "0")
8872    (set_attr "mode" "QI")])
8874 (define_split
8875   [(set (match_operand 0 "register_operand" "")
8876         (ior (match_operand 1 "register_operand" "")
8877              (match_operand 2 "const_int_operand" "")))
8878    (clobber (reg:CC FLAGS_REG))]
8879    "reload_completed
8880     && QI_REG_P (operands[0])
8881     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8882     && !(INTVAL (operands[2]) & ~(255 << 8))
8883     && GET_MODE (operands[0]) != QImode"
8884   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8885                    (ior:SI (zero_extract:SI (match_dup 1)
8886                                             (const_int 8) (const_int 8))
8887                            (match_dup 2)))
8888               (clobber (reg:CC FLAGS_REG))])]
8889   "operands[0] = gen_lowpart (SImode, operands[0]);
8890    operands[1] = gen_lowpart (SImode, operands[1]);
8891    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8893 ;; Since OR can be encoded with sign extended immediate, this is only
8894 ;; profitable when 7th bit is set.
8895 (define_split
8896   [(set (match_operand 0 "register_operand" "")
8897         (ior (match_operand 1 "general_operand" "")
8898              (match_operand 2 "const_int_operand" "")))
8899    (clobber (reg:CC FLAGS_REG))]
8900    "reload_completed
8901     && ANY_QI_REG_P (operands[0])
8902     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8903     && !(INTVAL (operands[2]) & ~255)
8904     && (INTVAL (operands[2]) & 128)
8905     && GET_MODE (operands[0]) != QImode"
8906   [(parallel [(set (strict_low_part (match_dup 0))
8907                    (ior:QI (match_dup 1)
8908                            (match_dup 2)))
8909               (clobber (reg:CC FLAGS_REG))])]
8910   "operands[0] = gen_lowpart (QImode, operands[0]);
8911    operands[1] = gen_lowpart (QImode, operands[1]);
8912    operands[2] = gen_lowpart (QImode, operands[2]);")
8914 ;; Logical XOR instructions
8916 ;; %%% This used to optimize known byte-wide and operations to memory.
8917 ;; If this is considered useful, it should be done with splitters.
8919 (define_expand "xordi3"
8920   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8921         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8922                 (match_operand:DI 2 "x86_64_general_operand" "")))
8923    (clobber (reg:CC FLAGS_REG))]
8924   "TARGET_64BIT"
8925   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8927 (define_insn "*xordi_1_rex64"
8928   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8929         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8930                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8931    (clobber (reg:CC FLAGS_REG))]
8932   "TARGET_64BIT
8933    && ix86_binary_operator_ok (XOR, DImode, operands)"
8934   "@
8935    xor{q}\t{%2, %0|%0, %2}
8936    xor{q}\t{%2, %0|%0, %2}"
8937   [(set_attr "type" "alu")
8938    (set_attr "mode" "DI,DI")])
8940 (define_insn "*xordi_2_rex64"
8941   [(set (reg FLAGS_REG)
8942         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8943                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8944                  (const_int 0)))
8945    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8946         (xor:DI (match_dup 1) (match_dup 2)))]
8947   "TARGET_64BIT
8948    && ix86_match_ccmode (insn, CCNOmode)
8949    && ix86_binary_operator_ok (XOR, DImode, operands)"
8950   "@
8951    xor{q}\t{%2, %0|%0, %2}
8952    xor{q}\t{%2, %0|%0, %2}"
8953   [(set_attr "type" "alu")
8954    (set_attr "mode" "DI,DI")])
8956 (define_insn "*xordi_3_rex64"
8957   [(set (reg FLAGS_REG)
8958         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8959                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8960                  (const_int 0)))
8961    (clobber (match_scratch:DI 0 "=r"))]
8962   "TARGET_64BIT
8963    && ix86_match_ccmode (insn, CCNOmode)
8964    && ix86_binary_operator_ok (XOR, DImode, operands)"
8965   "xor{q}\t{%2, %0|%0, %2}"
8966   [(set_attr "type" "alu")
8967    (set_attr "mode" "DI")])
8969 (define_expand "xorsi3"
8970   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8971         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8972                 (match_operand:SI 2 "general_operand" "")))
8973    (clobber (reg:CC FLAGS_REG))]
8974   ""
8975   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8977 (define_insn "*xorsi_1"
8978   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8979         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8980                 (match_operand:SI 2 "general_operand" "ri,rm")))
8981    (clobber (reg:CC FLAGS_REG))]
8982   "ix86_binary_operator_ok (XOR, SImode, operands)"
8983   "xor{l}\t{%2, %0|%0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "SI")])
8987 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8988 ;; Add speccase for immediates
8989 (define_insn "*xorsi_1_zext"
8990   [(set (match_operand:DI 0 "register_operand" "=r")
8991         (zero_extend:DI
8992           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8993                   (match_operand:SI 2 "general_operand" "rim"))))
8994    (clobber (reg:CC FLAGS_REG))]
8995   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8996   "xor{l}\t{%2, %k0|%k0, %2}"
8997   [(set_attr "type" "alu")
8998    (set_attr "mode" "SI")])
9000 (define_insn "*xorsi_1_zext_imm"
9001   [(set (match_operand:DI 0 "register_operand" "=r")
9002         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9003                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9004    (clobber (reg:CC FLAGS_REG))]
9005   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9006   "xor{l}\t{%2, %k0|%k0, %2}"
9007   [(set_attr "type" "alu")
9008    (set_attr "mode" "SI")])
9010 (define_insn "*xorsi_2"
9011   [(set (reg FLAGS_REG)
9012         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9013                          (match_operand:SI 2 "general_operand" "rim,ri"))
9014                  (const_int 0)))
9015    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9016         (xor:SI (match_dup 1) (match_dup 2)))]
9017   "ix86_match_ccmode (insn, CCNOmode)
9018    && ix86_binary_operator_ok (XOR, SImode, operands)"
9019   "xor{l}\t{%2, %0|%0, %2}"
9020   [(set_attr "type" "alu")
9021    (set_attr "mode" "SI")])
9023 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9024 ;; ??? Special case for immediate operand is missing - it is tricky.
9025 (define_insn "*xorsi_2_zext"
9026   [(set (reg FLAGS_REG)
9027         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9028                          (match_operand:SI 2 "general_operand" "rim"))
9029                  (const_int 0)))
9030    (set (match_operand:DI 0 "register_operand" "=r")
9031         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9032   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9033    && ix86_binary_operator_ok (XOR, SImode, operands)"
9034   "xor{l}\t{%2, %k0|%k0, %2}"
9035   [(set_attr "type" "alu")
9036    (set_attr "mode" "SI")])
9038 (define_insn "*xorsi_2_zext_imm"
9039   [(set (reg FLAGS_REG)
9040         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9041                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9042                  (const_int 0)))
9043    (set (match_operand:DI 0 "register_operand" "=r")
9044         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9045   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9046    && ix86_binary_operator_ok (XOR, SImode, operands)"
9047   "xor{l}\t{%2, %k0|%k0, %2}"
9048   [(set_attr "type" "alu")
9049    (set_attr "mode" "SI")])
9051 (define_insn "*xorsi_3"
9052   [(set (reg FLAGS_REG)
9053         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9054                          (match_operand:SI 2 "general_operand" "rim"))
9055                  (const_int 0)))
9056    (clobber (match_scratch:SI 0 "=r"))]
9057   "ix86_match_ccmode (insn, CCNOmode)
9058    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9059   "xor{l}\t{%2, %0|%0, %2}"
9060   [(set_attr "type" "alu")
9061    (set_attr "mode" "SI")])
9063 (define_expand "xorhi3"
9064   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9065         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9066                 (match_operand:HI 2 "general_operand" "")))
9067    (clobber (reg:CC FLAGS_REG))]
9068   "TARGET_HIMODE_MATH"
9069   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9071 (define_insn "*xorhi_1"
9072   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9073         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9074                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9075    (clobber (reg:CC FLAGS_REG))]
9076   "ix86_binary_operator_ok (XOR, HImode, operands)"
9077   "xor{w}\t{%2, %0|%0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "mode" "HI")])
9081 (define_insn "*xorhi_2"
9082   [(set (reg FLAGS_REG)
9083         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9084                          (match_operand:HI 2 "general_operand" "rim,ri"))
9085                  (const_int 0)))
9086    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9087         (xor:HI (match_dup 1) (match_dup 2)))]
9088   "ix86_match_ccmode (insn, CCNOmode)
9089    && ix86_binary_operator_ok (XOR, HImode, operands)"
9090   "xor{w}\t{%2, %0|%0, %2}"
9091   [(set_attr "type" "alu")
9092    (set_attr "mode" "HI")])
9094 (define_insn "*xorhi_3"
9095   [(set (reg FLAGS_REG)
9096         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9097                          (match_operand:HI 2 "general_operand" "rim"))
9098                  (const_int 0)))
9099    (clobber (match_scratch:HI 0 "=r"))]
9100   "ix86_match_ccmode (insn, CCNOmode)
9101    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9102   "xor{w}\t{%2, %0|%0, %2}"
9103   [(set_attr "type" "alu")
9104    (set_attr "mode" "HI")])
9106 (define_expand "xorqi3"
9107   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9108         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9109                 (match_operand:QI 2 "general_operand" "")))
9110    (clobber (reg:CC FLAGS_REG))]
9111   "TARGET_QIMODE_MATH"
9112   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9114 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9115 (define_insn "*xorqi_1"
9116   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9117         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9118                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9119    (clobber (reg:CC FLAGS_REG))]
9120   "ix86_binary_operator_ok (XOR, QImode, operands)"
9121   "@
9122    xor{b}\t{%2, %0|%0, %2}
9123    xor{b}\t{%2, %0|%0, %2}
9124    xor{l}\t{%k2, %k0|%k0, %k2}"
9125   [(set_attr "type" "alu")
9126    (set_attr "mode" "QI,QI,SI")])
9128 (define_insn "*xorqi_1_slp"
9129   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9130         (xor:QI (match_dup 0)
9131                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9132    (clobber (reg:CC FLAGS_REG))]
9133   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9134    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9135   "xor{b}\t{%1, %0|%0, %1}"
9136   [(set_attr "type" "alu1")
9137    (set_attr "mode" "QI")])
9139 (define_insn "xorqi_ext_0"
9140   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9141                          (const_int 8)
9142                          (const_int 8))
9143         (xor:SI
9144           (zero_extract:SI
9145             (match_operand 1 "ext_register_operand" "0")
9146             (const_int 8)
9147             (const_int 8))
9148           (match_operand 2 "const_int_operand" "n")))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9151   "xor{b}\t{%2, %h0|%h0, %2}"
9152   [(set_attr "type" "alu")
9153    (set_attr "length_immediate" "1")
9154    (set_attr "mode" "QI")])
9156 (define_insn "*xorqi_ext_1"
9157   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9158                          (const_int 8)
9159                          (const_int 8))
9160         (xor:SI
9161           (zero_extract:SI
9162             (match_operand 1 "ext_register_operand" "0")
9163             (const_int 8)
9164             (const_int 8))
9165           (zero_extend:SI
9166             (match_operand:QI 2 "general_operand" "Qm"))))
9167    (clobber (reg:CC FLAGS_REG))]
9168   "!TARGET_64BIT
9169    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170   "xor{b}\t{%2, %h0|%h0, %2}"
9171   [(set_attr "type" "alu")
9172    (set_attr "length_immediate" "0")
9173    (set_attr "mode" "QI")])
9175 (define_insn "*xorqi_ext_1_rex64"
9176   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9177                          (const_int 8)
9178                          (const_int 8))
9179         (xor:SI
9180           (zero_extract:SI
9181             (match_operand 1 "ext_register_operand" "0")
9182             (const_int 8)
9183             (const_int 8))
9184           (zero_extend:SI
9185             (match_operand 2 "ext_register_operand" "Q"))))
9186    (clobber (reg:CC FLAGS_REG))]
9187   "TARGET_64BIT
9188    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9189   "xor{b}\t{%2, %h0|%h0, %2}"
9190   [(set_attr "type" "alu")
9191    (set_attr "length_immediate" "0")
9192    (set_attr "mode" "QI")])
9194 (define_insn "*xorqi_ext_2"
9195   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9196                          (const_int 8)
9197                          (const_int 8))
9198         (xor:SI
9199           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9200                            (const_int 8)
9201                            (const_int 8))
9202           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9203                            (const_int 8)
9204                            (const_int 8))))
9205    (clobber (reg:CC FLAGS_REG))]
9206   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9207   "xor{b}\t{%h2, %h0|%h0, %h2}"
9208   [(set_attr "type" "alu")
9209    (set_attr "length_immediate" "0")
9210    (set_attr "mode" "QI")])
9212 (define_insn "*xorqi_cc_1"
9213   [(set (reg FLAGS_REG)
9214         (compare
9215           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9216                   (match_operand:QI 2 "general_operand" "qim,qi"))
9217           (const_int 0)))
9218    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9219         (xor:QI (match_dup 1) (match_dup 2)))]
9220   "ix86_match_ccmode (insn, CCNOmode)
9221    && ix86_binary_operator_ok (XOR, QImode, operands)"
9222   "xor{b}\t{%2, %0|%0, %2}"
9223   [(set_attr "type" "alu")
9224    (set_attr "mode" "QI")])
9226 (define_insn "*xorqi_2_slp"
9227   [(set (reg FLAGS_REG)
9228         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9229                          (match_operand:QI 1 "general_operand" "qim,qi"))
9230                  (const_int 0)))
9231    (set (strict_low_part (match_dup 0))
9232         (xor:QI (match_dup 0) (match_dup 1)))]
9233   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9234    && ix86_match_ccmode (insn, CCNOmode)
9235    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9236   "xor{b}\t{%1, %0|%0, %1}"
9237   [(set_attr "type" "alu1")
9238    (set_attr "mode" "QI")])
9240 (define_insn "*xorqi_cc_2"
9241   [(set (reg FLAGS_REG)
9242         (compare
9243           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9244                   (match_operand:QI 2 "general_operand" "qim"))
9245           (const_int 0)))
9246    (clobber (match_scratch:QI 0 "=q"))]
9247   "ix86_match_ccmode (insn, CCNOmode)
9248    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9249   "xor{b}\t{%2, %0|%0, %2}"
9250   [(set_attr "type" "alu")
9251    (set_attr "mode" "QI")])
9253 (define_insn "*xorqi_cc_ext_1"
9254   [(set (reg FLAGS_REG)
9255         (compare
9256           (xor:SI
9257             (zero_extract:SI
9258               (match_operand 1 "ext_register_operand" "0")
9259               (const_int 8)
9260               (const_int 8))
9261             (match_operand:QI 2 "general_operand" "qmn"))
9262           (const_int 0)))
9263    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9264                          (const_int 8)
9265                          (const_int 8))
9266         (xor:SI
9267           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9268           (match_dup 2)))]
9269   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9270   "xor{b}\t{%2, %h0|%h0, %2}"
9271   [(set_attr "type" "alu")
9272    (set_attr "mode" "QI")])
9274 (define_insn "*xorqi_cc_ext_1_rex64"
9275   [(set (reg FLAGS_REG)
9276         (compare
9277           (xor:SI
9278             (zero_extract:SI
9279               (match_operand 1 "ext_register_operand" "0")
9280               (const_int 8)
9281               (const_int 8))
9282             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9283           (const_int 0)))
9284    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
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   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9291   "xor{b}\t{%2, %h0|%h0, %2}"
9292   [(set_attr "type" "alu")
9293    (set_attr "mode" "QI")])
9295 (define_expand "xorqi_cc_ext_1"
9296   [(parallel [
9297      (set (reg:CCNO FLAGS_REG)
9298           (compare:CCNO
9299             (xor:SI
9300               (zero_extract:SI
9301                 (match_operand 1 "ext_register_operand" "")
9302                 (const_int 8)
9303                 (const_int 8))
9304               (match_operand:QI 2 "general_operand" ""))
9305             (const_int 0)))
9306      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9307                            (const_int 8)
9308                            (const_int 8))
9309           (xor:SI
9310             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9311             (match_dup 2)))])]
9312   ""
9313   "")
9315 (define_split
9316   [(set (match_operand 0 "register_operand" "")
9317         (xor (match_operand 1 "register_operand" "")
9318              (match_operand 2 "const_int_operand" "")))
9319    (clobber (reg:CC FLAGS_REG))]
9320    "reload_completed
9321     && QI_REG_P (operands[0])
9322     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9323     && !(INTVAL (operands[2]) & ~(255 << 8))
9324     && GET_MODE (operands[0]) != QImode"
9325   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9326                    (xor:SI (zero_extract:SI (match_dup 1)
9327                                             (const_int 8) (const_int 8))
9328                            (match_dup 2)))
9329               (clobber (reg:CC FLAGS_REG))])]
9330   "operands[0] = gen_lowpart (SImode, operands[0]);
9331    operands[1] = gen_lowpart (SImode, operands[1]);
9332    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9334 ;; Since XOR can be encoded with sign extended immediate, this is only
9335 ;; profitable when 7th bit is set.
9336 (define_split
9337   [(set (match_operand 0 "register_operand" "")
9338         (xor (match_operand 1 "general_operand" "")
9339              (match_operand 2 "const_int_operand" "")))
9340    (clobber (reg:CC FLAGS_REG))]
9341    "reload_completed
9342     && ANY_QI_REG_P (operands[0])
9343     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9344     && !(INTVAL (operands[2]) & ~255)
9345     && (INTVAL (operands[2]) & 128)
9346     && GET_MODE (operands[0]) != QImode"
9347   [(parallel [(set (strict_low_part (match_dup 0))
9348                    (xor:QI (match_dup 1)
9349                            (match_dup 2)))
9350               (clobber (reg:CC FLAGS_REG))])]
9351   "operands[0] = gen_lowpart (QImode, operands[0]);
9352    operands[1] = gen_lowpart (QImode, operands[1]);
9353    operands[2] = gen_lowpart (QImode, operands[2]);")
9355 ;; Negation instructions
9357 (define_expand "negti2"
9358   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9359                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9360               (clobber (reg:CC FLAGS_REG))])]
9361   "TARGET_64BIT"
9362   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9364 (define_insn "*negti2_1"
9365   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9366         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9367    (clobber (reg:CC FLAGS_REG))]
9368   "TARGET_64BIT
9369    && ix86_unary_operator_ok (NEG, TImode, operands)"
9370   "#")
9372 (define_split
9373   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9374         (neg:TI (match_operand:TI 1 "general_operand" "")))
9375    (clobber (reg:CC FLAGS_REG))]
9376   "TARGET_64BIT && reload_completed"
9377   [(parallel
9378     [(set (reg:CCZ FLAGS_REG)
9379           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9380      (set (match_dup 0) (neg:DI (match_dup 2)))])
9381    (parallel
9382     [(set (match_dup 1)
9383           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9384                             (match_dup 3))
9385                    (const_int 0)))
9386      (clobber (reg:CC FLAGS_REG))])
9387    (parallel
9388     [(set (match_dup 1)
9389           (neg:DI (match_dup 1)))
9390      (clobber (reg:CC FLAGS_REG))])]
9391   "split_ti (operands+1, 1, operands+2, operands+3);
9392    split_ti (operands+0, 1, operands+0, operands+1);")
9394 (define_expand "negdi2"
9395   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9396                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9397               (clobber (reg:CC FLAGS_REG))])]
9398   ""
9399   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9401 (define_insn "*negdi2_1"
9402   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9403         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9404    (clobber (reg:CC FLAGS_REG))]
9405   "!TARGET_64BIT
9406    && ix86_unary_operator_ok (NEG, DImode, operands)"
9407   "#")
9409 (define_split
9410   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9411         (neg:DI (match_operand:DI 1 "general_operand" "")))
9412    (clobber (reg:CC FLAGS_REG))]
9413   "!TARGET_64BIT && reload_completed"
9414   [(parallel
9415     [(set (reg:CCZ FLAGS_REG)
9416           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9417      (set (match_dup 0) (neg:SI (match_dup 2)))])
9418    (parallel
9419     [(set (match_dup 1)
9420           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9421                             (match_dup 3))
9422                    (const_int 0)))
9423      (clobber (reg:CC FLAGS_REG))])
9424    (parallel
9425     [(set (match_dup 1)
9426           (neg:SI (match_dup 1)))
9427      (clobber (reg:CC FLAGS_REG))])]
9428   "split_di (operands+1, 1, operands+2, operands+3);
9429    split_di (operands+0, 1, operands+0, operands+1);")
9431 (define_insn "*negdi2_1_rex64"
9432   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9433         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9434    (clobber (reg:CC FLAGS_REG))]
9435   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9436   "neg{q}\t%0"
9437   [(set_attr "type" "negnot")
9438    (set_attr "mode" "DI")])
9440 ;; The problem with neg is that it does not perform (compare x 0),
9441 ;; it really performs (compare 0 x), which leaves us with the zero
9442 ;; flag being the only useful item.
9444 (define_insn "*negdi2_cmpz_rex64"
9445   [(set (reg:CCZ FLAGS_REG)
9446         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9447                      (const_int 0)))
9448    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9449         (neg:DI (match_dup 1)))]
9450   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9451   "neg{q}\t%0"
9452   [(set_attr "type" "negnot")
9453    (set_attr "mode" "DI")])
9456 (define_expand "negsi2"
9457   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9458                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9459               (clobber (reg:CC FLAGS_REG))])]
9460   ""
9461   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9463 (define_insn "*negsi2_1"
9464   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9465         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9466    (clobber (reg:CC FLAGS_REG))]
9467   "ix86_unary_operator_ok (NEG, SImode, operands)"
9468   "neg{l}\t%0"
9469   [(set_attr "type" "negnot")
9470    (set_attr "mode" "SI")])
9472 ;; Combine is quite creative about this pattern.
9473 (define_insn "*negsi2_1_zext"
9474   [(set (match_operand:DI 0 "register_operand" "=r")
9475         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9476                                         (const_int 32)))
9477                      (const_int 32)))
9478    (clobber (reg:CC FLAGS_REG))]
9479   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9480   "neg{l}\t%k0"
9481   [(set_attr "type" "negnot")
9482    (set_attr "mode" "SI")])
9484 ;; The problem with neg is that it does not perform (compare x 0),
9485 ;; it really performs (compare 0 x), which leaves us with the zero
9486 ;; flag being the only useful item.
9488 (define_insn "*negsi2_cmpz"
9489   [(set (reg:CCZ FLAGS_REG)
9490         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9491                      (const_int 0)))
9492    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9493         (neg:SI (match_dup 1)))]
9494   "ix86_unary_operator_ok (NEG, SImode, operands)"
9495   "neg{l}\t%0"
9496   [(set_attr "type" "negnot")
9497    (set_attr "mode" "SI")])
9499 (define_insn "*negsi2_cmpz_zext"
9500   [(set (reg:CCZ FLAGS_REG)
9501         (compare:CCZ (lshiftrt:DI
9502                        (neg:DI (ashift:DI
9503                                  (match_operand:DI 1 "register_operand" "0")
9504                                  (const_int 32)))
9505                        (const_int 32))
9506                      (const_int 0)))
9507    (set (match_operand:DI 0 "register_operand" "=r")
9508         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9509                                         (const_int 32)))
9510                      (const_int 32)))]
9511   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9512   "neg{l}\t%k0"
9513   [(set_attr "type" "negnot")
9514    (set_attr "mode" "SI")])
9516 (define_expand "neghi2"
9517   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9518                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9519               (clobber (reg:CC FLAGS_REG))])]
9520   "TARGET_HIMODE_MATH"
9521   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9523 (define_insn "*neghi2_1"
9524   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9525         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9526    (clobber (reg:CC FLAGS_REG))]
9527   "ix86_unary_operator_ok (NEG, HImode, operands)"
9528   "neg{w}\t%0"
9529   [(set_attr "type" "negnot")
9530    (set_attr "mode" "HI")])
9532 (define_insn "*neghi2_cmpz"
9533   [(set (reg:CCZ FLAGS_REG)
9534         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9535                      (const_int 0)))
9536    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9537         (neg:HI (match_dup 1)))]
9538   "ix86_unary_operator_ok (NEG, HImode, operands)"
9539   "neg{w}\t%0"
9540   [(set_attr "type" "negnot")
9541    (set_attr "mode" "HI")])
9543 (define_expand "negqi2"
9544   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9545                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9546               (clobber (reg:CC FLAGS_REG))])]
9547   "TARGET_QIMODE_MATH"
9548   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9550 (define_insn "*negqi2_1"
9551   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9552         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9553    (clobber (reg:CC FLAGS_REG))]
9554   "ix86_unary_operator_ok (NEG, QImode, operands)"
9555   "neg{b}\t%0"
9556   [(set_attr "type" "negnot")
9557    (set_attr "mode" "QI")])
9559 (define_insn "*negqi2_cmpz"
9560   [(set (reg:CCZ FLAGS_REG)
9561         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9562                      (const_int 0)))
9563    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9564         (neg:QI (match_dup 1)))]
9565   "ix86_unary_operator_ok (NEG, QImode, operands)"
9566   "neg{b}\t%0"
9567   [(set_attr "type" "negnot")
9568    (set_attr "mode" "QI")])
9570 ;; Changing of sign for FP values is doable using integer unit too.
9572 (define_expand "negsf2"
9573   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9574         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9575   "TARGET_80387 || TARGET_SSE_MATH"
9576   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9578 (define_expand "abssf2"
9579   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9580         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9581   "TARGET_80387 || TARGET_SSE_MATH"
9582   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9584 (define_insn "*absnegsf2_mixed"
9585   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9586         (match_operator:SF 3 "absneg_operator"
9587           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9588    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9589    (clobber (reg:CC FLAGS_REG))]
9590   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9591    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9592   "#")
9594 (define_insn "*absnegsf2_sse"
9595   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9596         (match_operator:SF 3 "absneg_operator"
9597           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9598    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9599    (clobber (reg:CC FLAGS_REG))]
9600   "TARGET_SSE_MATH
9601    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9602   "#")
9604 (define_insn "*absnegsf2_i387"
9605   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9606         (match_operator:SF 3 "absneg_operator"
9607           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9608    (use (match_operand 2 "" ""))
9609    (clobber (reg:CC FLAGS_REG))]
9610   "TARGET_80387 && !TARGET_SSE_MATH
9611    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9612   "#")
9614 (define_expand "copysignsf3"
9615   [(match_operand:SF 0 "register_operand" "")
9616    (match_operand:SF 1 "nonmemory_operand" "")
9617    (match_operand:SF 2 "register_operand" "")]
9618   "TARGET_SSE_MATH"
9620   ix86_expand_copysign (operands);
9621   DONE;
9624 (define_insn_and_split "copysignsf3_const"
9625   [(set (match_operand:SF 0 "register_operand"          "=x")
9626         (unspec:SF
9627           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9628            (match_operand:SF 2 "register_operand"       "0")
9629            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9630           UNSPEC_COPYSIGN))]
9631   "TARGET_SSE_MATH"
9632   "#"
9633   "&& reload_completed"
9634   [(const_int 0)]
9636   ix86_split_copysign_const (operands);
9637   DONE;
9640 (define_insn "copysignsf3_var"
9641   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9642         (unspec:SF
9643           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9644            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9645            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9646            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9647           UNSPEC_COPYSIGN))
9648    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9649   "TARGET_SSE_MATH"
9650   "#")
9652 (define_split
9653   [(set (match_operand:SF 0 "register_operand" "")
9654         (unspec:SF
9655           [(match_operand:SF 2 "register_operand" "")
9656            (match_operand:SF 3 "register_operand" "")
9657            (match_operand:V4SF 4 "" "")
9658            (match_operand:V4SF 5 "" "")]
9659           UNSPEC_COPYSIGN))
9660    (clobber (match_scratch:V4SF 1 ""))]
9661   "TARGET_SSE_MATH && reload_completed"
9662   [(const_int 0)]
9664   ix86_split_copysign_var (operands);
9665   DONE;
9668 (define_expand "negdf2"
9669   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9670         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9671   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9672   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9674 (define_expand "absdf2"
9675   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9676         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9677   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9678   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9680 (define_insn "*absnegdf2_mixed"
9681   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9682         (match_operator:DF 3 "absneg_operator"
9683           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9684    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9685    (clobber (reg:CC FLAGS_REG))]
9686   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9687    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9688   "#")
9690 (define_insn "*absnegdf2_sse"
9691   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9692         (match_operator:DF 3 "absneg_operator"
9693           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9694    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9695    (clobber (reg:CC FLAGS_REG))]
9696   "TARGET_SSE2 && TARGET_SSE_MATH
9697    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9698   "#")
9700 (define_insn "*absnegdf2_i387"
9701   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9702         (match_operator:DF 3 "absneg_operator"
9703           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9704    (use (match_operand 2 "" ""))
9705    (clobber (reg:CC FLAGS_REG))]
9706   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9707    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9708   "#")
9710 (define_expand "copysigndf3"
9711   [(match_operand:DF 0 "register_operand" "")
9712    (match_operand:DF 1 "nonmemory_operand" "")
9713    (match_operand:DF 2 "register_operand" "")]
9714   "TARGET_SSE2 && TARGET_SSE_MATH"
9716   ix86_expand_copysign (operands);
9717   DONE;
9720 (define_insn_and_split "copysigndf3_const"
9721   [(set (match_operand:DF 0 "register_operand"          "=x")
9722         (unspec:DF
9723           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9724            (match_operand:DF 2 "register_operand"       "0")
9725            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9726           UNSPEC_COPYSIGN))]
9727   "TARGET_SSE2 && TARGET_SSE_MATH"
9728   "#"
9729   "&& reload_completed"
9730   [(const_int 0)]
9732   ix86_split_copysign_const (operands);
9733   DONE;
9736 (define_insn "copysigndf3_var"
9737   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9738         (unspec:DF
9739           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9740            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9741            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9742            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9743           UNSPEC_COPYSIGN))
9744    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9745   "TARGET_SSE2 && TARGET_SSE_MATH"
9746   "#")
9748 (define_split
9749   [(set (match_operand:DF 0 "register_operand" "")
9750         (unspec:DF
9751           [(match_operand:DF 2 "register_operand" "")
9752            (match_operand:DF 3 "register_operand" "")
9753            (match_operand:V2DF 4 "" "")
9754            (match_operand:V2DF 5 "" "")]
9755           UNSPEC_COPYSIGN))
9756    (clobber (match_scratch:V2DF 1 ""))]
9757   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9758   [(const_int 0)]
9760   ix86_split_copysign_var (operands);
9761   DONE;
9764 (define_expand "negxf2"
9765   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9766         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9767   "TARGET_80387"
9768   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9770 (define_expand "absxf2"
9771   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9772         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9773   "TARGET_80387"
9774   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9776 (define_insn "*absnegxf2_i387"
9777   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9778         (match_operator:XF 3 "absneg_operator"
9779           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9780    (use (match_operand 2 "" ""))
9781    (clobber (reg:CC FLAGS_REG))]
9782   "TARGET_80387
9783    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9784   "#")
9786 ;; Splitters for fp abs and neg.
9788 (define_split
9789   [(set (match_operand 0 "fp_register_operand" "")
9790         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9791    (use (match_operand 2 "" ""))
9792    (clobber (reg:CC FLAGS_REG))]
9793   "reload_completed"
9794   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9796 (define_split
9797   [(set (match_operand 0 "register_operand" "")
9798         (match_operator 3 "absneg_operator"
9799           [(match_operand 1 "register_operand" "")]))
9800    (use (match_operand 2 "nonimmediate_operand" ""))
9801    (clobber (reg:CC FLAGS_REG))]
9802   "reload_completed && SSE_REG_P (operands[0])"
9803   [(set (match_dup 0) (match_dup 3))]
9805   enum machine_mode mode = GET_MODE (operands[0]);
9806   enum machine_mode vmode = GET_MODE (operands[2]);
9807   rtx tmp;
9809   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9810   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9811   if (operands_match_p (operands[0], operands[2]))
9812     {
9813       tmp = operands[1];
9814       operands[1] = operands[2];
9815       operands[2] = tmp;
9816     }
9817   if (GET_CODE (operands[3]) == ABS)
9818     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9819   else
9820     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9821   operands[3] = tmp;
9824 (define_split
9825   [(set (match_operand:SF 0 "register_operand" "")
9826         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9827    (use (match_operand:V4SF 2 "" ""))
9828    (clobber (reg:CC FLAGS_REG))]
9829   "reload_completed"
9830   [(parallel [(set (match_dup 0) (match_dup 1))
9831               (clobber (reg:CC FLAGS_REG))])]
9833   rtx tmp;
9834   operands[0] = gen_lowpart (SImode, operands[0]);
9835   if (GET_CODE (operands[1]) == ABS)
9836     {
9837       tmp = gen_int_mode (0x7fffffff, SImode);
9838       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9839     }
9840   else
9841     {
9842       tmp = gen_int_mode (0x80000000, SImode);
9843       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9844     }
9845   operands[1] = tmp;
9848 (define_split
9849   [(set (match_operand:DF 0 "register_operand" "")
9850         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9851    (use (match_operand 2 "" ""))
9852    (clobber (reg:CC FLAGS_REG))]
9853   "reload_completed"
9854   [(parallel [(set (match_dup 0) (match_dup 1))
9855               (clobber (reg:CC FLAGS_REG))])]
9857   rtx tmp;
9858   if (TARGET_64BIT)
9859     {
9860       tmp = gen_lowpart (DImode, operands[0]);
9861       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9862       operands[0] = tmp;
9864       if (GET_CODE (operands[1]) == ABS)
9865         tmp = const0_rtx;
9866       else
9867         tmp = gen_rtx_NOT (DImode, tmp);
9868     }
9869   else
9870     {
9871       operands[0] = gen_highpart (SImode, operands[0]);
9872       if (GET_CODE (operands[1]) == ABS)
9873         {
9874           tmp = gen_int_mode (0x7fffffff, SImode);
9875           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9876         }
9877       else
9878         {
9879           tmp = gen_int_mode (0x80000000, SImode);
9880           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9881         }
9882     }
9883   operands[1] = tmp;
9886 (define_split
9887   [(set (match_operand:XF 0 "register_operand" "")
9888         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9889    (use (match_operand 2 "" ""))
9890    (clobber (reg:CC FLAGS_REG))]
9891   "reload_completed"
9892   [(parallel [(set (match_dup 0) (match_dup 1))
9893               (clobber (reg:CC FLAGS_REG))])]
9895   rtx tmp;
9896   operands[0] = gen_rtx_REG (SImode,
9897                              true_regnum (operands[0])
9898                              + (TARGET_64BIT ? 1 : 2));
9899   if (GET_CODE (operands[1]) == ABS)
9900     {
9901       tmp = GEN_INT (0x7fff);
9902       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9903     }
9904   else
9905     {
9906       tmp = GEN_INT (0x8000);
9907       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9908     }
9909   operands[1] = tmp;
9912 (define_split
9913   [(set (match_operand 0 "memory_operand" "")
9914         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9915    (use (match_operand 2 "" ""))
9916    (clobber (reg:CC FLAGS_REG))]
9917   "reload_completed"
9918   [(parallel [(set (match_dup 0) (match_dup 1))
9919               (clobber (reg:CC FLAGS_REG))])]
9921   enum machine_mode mode = GET_MODE (operands[0]);
9922   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9923   rtx tmp;
9925   operands[0] = adjust_address (operands[0], QImode, size - 1);
9926   if (GET_CODE (operands[1]) == ABS)
9927     {
9928       tmp = gen_int_mode (0x7f, QImode);
9929       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9930     }
9931   else
9932     {
9933       tmp = gen_int_mode (0x80, QImode);
9934       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9935     }
9936   operands[1] = tmp;
9939 ;; Conditionalize these after reload. If they match before reload, we
9940 ;; lose the clobber and ability to use integer instructions.
9942 (define_insn "*negsf2_1"
9943   [(set (match_operand:SF 0 "register_operand" "=f")
9944         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9945   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9946   "fchs"
9947   [(set_attr "type" "fsgn")
9948    (set_attr "mode" "SF")])
9950 (define_insn "*negdf2_1"
9951   [(set (match_operand:DF 0 "register_operand" "=f")
9952         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9953   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9954   "fchs"
9955   [(set_attr "type" "fsgn")
9956    (set_attr "mode" "DF")])
9958 (define_insn "*negxf2_1"
9959   [(set (match_operand:XF 0 "register_operand" "=f")
9960         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9961   "TARGET_80387"
9962   "fchs"
9963   [(set_attr "type" "fsgn")
9964    (set_attr "mode" "XF")])
9966 (define_insn "*abssf2_1"
9967   [(set (match_operand:SF 0 "register_operand" "=f")
9968         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9969   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9970   "fabs"
9971   [(set_attr "type" "fsgn")
9972    (set_attr "mode" "SF")])
9974 (define_insn "*absdf2_1"
9975   [(set (match_operand:DF 0 "register_operand" "=f")
9976         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9977   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9978   "fabs"
9979   [(set_attr "type" "fsgn")
9980    (set_attr "mode" "DF")])
9982 (define_insn "*absxf2_1"
9983   [(set (match_operand:XF 0 "register_operand" "=f")
9984         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9985   "TARGET_80387"
9986   "fabs"
9987   [(set_attr "type" "fsgn")
9988    (set_attr "mode" "DF")])
9990 (define_insn "*negextendsfdf2"
9991   [(set (match_operand:DF 0 "register_operand" "=f")
9992         (neg:DF (float_extend:DF
9993                   (match_operand:SF 1 "register_operand" "0"))))]
9994   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9995   "fchs"
9996   [(set_attr "type" "fsgn")
9997    (set_attr "mode" "DF")])
9999 (define_insn "*negextenddfxf2"
10000   [(set (match_operand:XF 0 "register_operand" "=f")
10001         (neg:XF (float_extend:XF
10002                   (match_operand:DF 1 "register_operand" "0"))))]
10003   "TARGET_80387"
10004   "fchs"
10005   [(set_attr "type" "fsgn")
10006    (set_attr "mode" "XF")])
10008 (define_insn "*negextendsfxf2"
10009   [(set (match_operand:XF 0 "register_operand" "=f")
10010         (neg:XF (float_extend:XF
10011                   (match_operand:SF 1 "register_operand" "0"))))]
10012   "TARGET_80387"
10013   "fchs"
10014   [(set_attr "type" "fsgn")
10015    (set_attr "mode" "XF")])
10017 (define_insn "*absextendsfdf2"
10018   [(set (match_operand:DF 0 "register_operand" "=f")
10019         (abs:DF (float_extend:DF
10020                   (match_operand:SF 1 "register_operand" "0"))))]
10021   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10022   "fabs"
10023   [(set_attr "type" "fsgn")
10024    (set_attr "mode" "DF")])
10026 (define_insn "*absextenddfxf2"
10027   [(set (match_operand:XF 0 "register_operand" "=f")
10028         (abs:XF (float_extend:XF
10029           (match_operand:DF 1 "register_operand" "0"))))]
10030   "TARGET_80387"
10031   "fabs"
10032   [(set_attr "type" "fsgn")
10033    (set_attr "mode" "XF")])
10035 (define_insn "*absextendsfxf2"
10036   [(set (match_operand:XF 0 "register_operand" "=f")
10037         (abs:XF (float_extend:XF
10038           (match_operand:SF 1 "register_operand" "0"))))]
10039   "TARGET_80387"
10040   "fabs"
10041   [(set_attr "type" "fsgn")
10042    (set_attr "mode" "XF")])
10044 ;; One complement instructions
10046 (define_expand "one_cmpldi2"
10047   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10048         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10049   "TARGET_64BIT"
10050   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10052 (define_insn "*one_cmpldi2_1_rex64"
10053   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10054         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10055   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10056   "not{q}\t%0"
10057   [(set_attr "type" "negnot")
10058    (set_attr "mode" "DI")])
10060 (define_insn "*one_cmpldi2_2_rex64"
10061   [(set (reg FLAGS_REG)
10062         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10063                  (const_int 0)))
10064    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10065         (not:DI (match_dup 1)))]
10066   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10067    && ix86_unary_operator_ok (NOT, DImode, operands)"
10068   "#"
10069   [(set_attr "type" "alu1")
10070    (set_attr "mode" "DI")])
10072 (define_split
10073   [(set (match_operand 0 "flags_reg_operand" "")
10074         (match_operator 2 "compare_operator"
10075           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10076            (const_int 0)]))
10077    (set (match_operand:DI 1 "nonimmediate_operand" "")
10078         (not:DI (match_dup 3)))]
10079   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10080   [(parallel [(set (match_dup 0)
10081                    (match_op_dup 2
10082                      [(xor:DI (match_dup 3) (const_int -1))
10083                       (const_int 0)]))
10084               (set (match_dup 1)
10085                    (xor:DI (match_dup 3) (const_int -1)))])]
10086   "")
10088 (define_expand "one_cmplsi2"
10089   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10090         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10091   ""
10092   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10094 (define_insn "*one_cmplsi2_1"
10095   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10096         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10097   "ix86_unary_operator_ok (NOT, SImode, operands)"
10098   "not{l}\t%0"
10099   [(set_attr "type" "negnot")
10100    (set_attr "mode" "SI")])
10102 ;; ??? Currently never generated - xor is used instead.
10103 (define_insn "*one_cmplsi2_1_zext"
10104   [(set (match_operand:DI 0 "register_operand" "=r")
10105         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10106   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10107   "not{l}\t%k0"
10108   [(set_attr "type" "negnot")
10109    (set_attr "mode" "SI")])
10111 (define_insn "*one_cmplsi2_2"
10112   [(set (reg FLAGS_REG)
10113         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10114                  (const_int 0)))
10115    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10116         (not:SI (match_dup 1)))]
10117   "ix86_match_ccmode (insn, CCNOmode)
10118    && ix86_unary_operator_ok (NOT, SImode, operands)"
10119   "#"
10120   [(set_attr "type" "alu1")
10121    (set_attr "mode" "SI")])
10123 (define_split
10124   [(set (match_operand 0 "flags_reg_operand" "")
10125         (match_operator 2 "compare_operator"
10126           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10127            (const_int 0)]))
10128    (set (match_operand:SI 1 "nonimmediate_operand" "")
10129         (not:SI (match_dup 3)))]
10130   "ix86_match_ccmode (insn, CCNOmode)"
10131   [(parallel [(set (match_dup 0)
10132                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10133                                     (const_int 0)]))
10134               (set (match_dup 1)
10135                    (xor:SI (match_dup 3) (const_int -1)))])]
10136   "")
10138 ;; ??? Currently never generated - xor is used instead.
10139 (define_insn "*one_cmplsi2_2_zext"
10140   [(set (reg FLAGS_REG)
10141         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10142                  (const_int 0)))
10143    (set (match_operand:DI 0 "register_operand" "=r")
10144         (zero_extend:DI (not:SI (match_dup 1))))]
10145   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10146    && ix86_unary_operator_ok (NOT, SImode, operands)"
10147   "#"
10148   [(set_attr "type" "alu1")
10149    (set_attr "mode" "SI")])
10151 (define_split
10152   [(set (match_operand 0 "flags_reg_operand" "")
10153         (match_operator 2 "compare_operator"
10154           [(not:SI (match_operand:SI 3 "register_operand" ""))
10155            (const_int 0)]))
10156    (set (match_operand:DI 1 "register_operand" "")
10157         (zero_extend:DI (not:SI (match_dup 3))))]
10158   "ix86_match_ccmode (insn, CCNOmode)"
10159   [(parallel [(set (match_dup 0)
10160                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10161                                     (const_int 0)]))
10162               (set (match_dup 1)
10163                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10164   "")
10166 (define_expand "one_cmplhi2"
10167   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10168         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10169   "TARGET_HIMODE_MATH"
10170   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10172 (define_insn "*one_cmplhi2_1"
10173   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10174         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10175   "ix86_unary_operator_ok (NOT, HImode, operands)"
10176   "not{w}\t%0"
10177   [(set_attr "type" "negnot")
10178    (set_attr "mode" "HI")])
10180 (define_insn "*one_cmplhi2_2"
10181   [(set (reg FLAGS_REG)
10182         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10183                  (const_int 0)))
10184    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10185         (not:HI (match_dup 1)))]
10186   "ix86_match_ccmode (insn, CCNOmode)
10187    && ix86_unary_operator_ok (NEG, HImode, operands)"
10188   "#"
10189   [(set_attr "type" "alu1")
10190    (set_attr "mode" "HI")])
10192 (define_split
10193   [(set (match_operand 0 "flags_reg_operand" "")
10194         (match_operator 2 "compare_operator"
10195           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10196            (const_int 0)]))
10197    (set (match_operand:HI 1 "nonimmediate_operand" "")
10198         (not:HI (match_dup 3)))]
10199   "ix86_match_ccmode (insn, CCNOmode)"
10200   [(parallel [(set (match_dup 0)
10201                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10202                                     (const_int 0)]))
10203               (set (match_dup 1)
10204                    (xor:HI (match_dup 3) (const_int -1)))])]
10205   "")
10207 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10208 (define_expand "one_cmplqi2"
10209   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10210         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10211   "TARGET_QIMODE_MATH"
10212   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10214 (define_insn "*one_cmplqi2_1"
10215   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10216         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10217   "ix86_unary_operator_ok (NOT, QImode, operands)"
10218   "@
10219    not{b}\t%0
10220    not{l}\t%k0"
10221   [(set_attr "type" "negnot")
10222    (set_attr "mode" "QI,SI")])
10224 (define_insn "*one_cmplqi2_2"
10225   [(set (reg FLAGS_REG)
10226         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10227                  (const_int 0)))
10228    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10229         (not:QI (match_dup 1)))]
10230   "ix86_match_ccmode (insn, CCNOmode)
10231    && ix86_unary_operator_ok (NOT, QImode, operands)"
10232   "#"
10233   [(set_attr "type" "alu1")
10234    (set_attr "mode" "QI")])
10236 (define_split
10237   [(set (match_operand 0 "flags_reg_operand" "")
10238         (match_operator 2 "compare_operator"
10239           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10240            (const_int 0)]))
10241    (set (match_operand:QI 1 "nonimmediate_operand" "")
10242         (not:QI (match_dup 3)))]
10243   "ix86_match_ccmode (insn, CCNOmode)"
10244   [(parallel [(set (match_dup 0)
10245                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10246                                     (const_int 0)]))
10247               (set (match_dup 1)
10248                    (xor:QI (match_dup 3) (const_int -1)))])]
10249   "")
10251 ;; Arithmetic shift instructions
10253 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10254 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10255 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10256 ;; from the assembler input.
10258 ;; This instruction shifts the target reg/mem as usual, but instead of
10259 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10260 ;; is a left shift double, bits are taken from the high order bits of
10261 ;; reg, else if the insn is a shift right double, bits are taken from the
10262 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10263 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10265 ;; Since sh[lr]d does not change the `reg' operand, that is done
10266 ;; separately, making all shifts emit pairs of shift double and normal
10267 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10268 ;; support a 63 bit shift, each shift where the count is in a reg expands
10269 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10271 ;; If the shift count is a constant, we need never emit more than one
10272 ;; shift pair, instead using moves and sign extension for counts greater
10273 ;; than 31.
10275 (define_expand "ashlti3"
10276   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10277                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10278                               (match_operand:QI 2 "nonmemory_operand" "")))
10279               (clobber (reg:CC FLAGS_REG))])]
10280   "TARGET_64BIT"
10282   if (! immediate_operand (operands[2], QImode))
10283     {
10284       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10285       DONE;
10286     }
10287   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10288   DONE;
10291 (define_insn "ashlti3_1"
10292   [(set (match_operand:TI 0 "register_operand" "=r")
10293         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10294                    (match_operand:QI 2 "register_operand" "c")))
10295    (clobber (match_scratch:DI 3 "=&r"))
10296    (clobber (reg:CC FLAGS_REG))]
10297   "TARGET_64BIT"
10298   "#"
10299   [(set_attr "type" "multi")])
10301 (define_insn "*ashlti3_2"
10302   [(set (match_operand:TI 0 "register_operand" "=r")
10303         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10304                    (match_operand:QI 2 "immediate_operand" "O")))
10305    (clobber (reg:CC FLAGS_REG))]
10306   "TARGET_64BIT"
10307   "#"
10308   [(set_attr "type" "multi")])
10310 (define_split
10311   [(set (match_operand:TI 0 "register_operand" "")
10312         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10313                    (match_operand:QI 2 "register_operand" "")))
10314    (clobber (match_scratch:DI 3 ""))
10315    (clobber (reg:CC FLAGS_REG))]
10316   "TARGET_64BIT && reload_completed"
10317   [(const_int 0)]
10318   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10320 (define_split
10321   [(set (match_operand:TI 0 "register_operand" "")
10322         (ashift:TI (match_operand:TI 1 "register_operand" "")
10323                    (match_operand:QI 2 "immediate_operand" "")))
10324    (clobber (reg:CC FLAGS_REG))]
10325   "TARGET_64BIT && reload_completed"
10326   [(const_int 0)]
10327   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10329 (define_insn "x86_64_shld"
10330   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10331         (ior:DI (ashift:DI (match_dup 0)
10332                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10333                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10334                   (minus:QI (const_int 64) (match_dup 2)))))
10335    (clobber (reg:CC FLAGS_REG))]
10336   "TARGET_64BIT"
10337   "@
10338    shld{q}\t{%2, %1, %0|%0, %1, %2}
10339    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10340   [(set_attr "type" "ishift")
10341    (set_attr "prefix_0f" "1")
10342    (set_attr "mode" "DI")
10343    (set_attr "athlon_decode" "vector")])
10345 (define_expand "x86_64_shift_adj"
10346   [(set (reg:CCZ FLAGS_REG)
10347         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10348                              (const_int 64))
10349                      (const_int 0)))
10350    (set (match_operand:DI 0 "register_operand" "")
10351         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10352                          (match_operand:DI 1 "register_operand" "")
10353                          (match_dup 0)))
10354    (set (match_dup 1)
10355         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10356                          (match_operand:DI 3 "register_operand" "r")
10357                          (match_dup 1)))]
10358   "TARGET_64BIT"
10359   "")
10361 (define_expand "ashldi3"
10362   [(set (match_operand:DI 0 "shiftdi_operand" "")
10363         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10364                    (match_operand:QI 2 "nonmemory_operand" "")))]
10365   ""
10366   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10368 (define_insn "*ashldi3_1_rex64"
10369   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10370         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10371                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10372    (clobber (reg:CC FLAGS_REG))]
10373   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10375   switch (get_attr_type (insn))
10376     {
10377     case TYPE_ALU:
10378       gcc_assert (operands[2] == const1_rtx);
10379       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10380       return "add{q}\t{%0, %0|%0, %0}";
10382     case TYPE_LEA:
10383       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10384       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10385       operands[1] = gen_rtx_MULT (DImode, operands[1],
10386                                   GEN_INT (1 << INTVAL (operands[2])));
10387       return "lea{q}\t{%a1, %0|%0, %a1}";
10389     default:
10390       if (REG_P (operands[2]))
10391         return "sal{q}\t{%b2, %0|%0, %b2}";
10392       else if (operands[2] == const1_rtx
10393                && (TARGET_SHIFT1 || optimize_size))
10394         return "sal{q}\t%0";
10395       else
10396         return "sal{q}\t{%2, %0|%0, %2}";
10397     }
10399   [(set (attr "type")
10400      (cond [(eq_attr "alternative" "1")
10401               (const_string "lea")
10402             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10403                           (const_int 0))
10404                       (match_operand 0 "register_operand" ""))
10405                  (match_operand 2 "const1_operand" ""))
10406               (const_string "alu")
10407            ]
10408            (const_string "ishift")))
10409    (set_attr "mode" "DI")])
10411 ;; Convert lea to the lea pattern to avoid flags dependency.
10412 (define_split
10413   [(set (match_operand:DI 0 "register_operand" "")
10414         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10415                    (match_operand:QI 2 "immediate_operand" "")))
10416    (clobber (reg:CC FLAGS_REG))]
10417   "TARGET_64BIT && reload_completed
10418    && true_regnum (operands[0]) != true_regnum (operands[1])"
10419   [(set (match_dup 0)
10420         (mult:DI (match_dup 1)
10421                  (match_dup 2)))]
10422   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10424 ;; This pattern can't accept a variable shift count, since shifts by
10425 ;; zero don't affect the flags.  We assume that shifts by constant
10426 ;; zero are optimized away.
10427 (define_insn "*ashldi3_cmp_rex64"
10428   [(set (reg FLAGS_REG)
10429         (compare
10430           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10431                      (match_operand:QI 2 "immediate_operand" "e"))
10432           (const_int 0)))
10433    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10434         (ashift:DI (match_dup 1) (match_dup 2)))]
10435   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10436    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10437    && (optimize_size
10438        || !TARGET_PARTIAL_FLAG_REG_STALL
10439        || (operands[2] == const1_rtx
10440            && (TARGET_SHIFT1
10441                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10443   switch (get_attr_type (insn))
10444     {
10445     case TYPE_ALU:
10446       gcc_assert (operands[2] == const1_rtx);
10447       return "add{q}\t{%0, %0|%0, %0}";
10449     default:
10450       if (REG_P (operands[2]))
10451         return "sal{q}\t{%b2, %0|%0, %b2}";
10452       else if (operands[2] == const1_rtx
10453                && (TARGET_SHIFT1 || optimize_size))
10454         return "sal{q}\t%0";
10455       else
10456         return "sal{q}\t{%2, %0|%0, %2}";
10457     }
10459   [(set (attr "type")
10460      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10461                           (const_int 0))
10462                       (match_operand 0 "register_operand" ""))
10463                  (match_operand 2 "const1_operand" ""))
10464               (const_string "alu")
10465            ]
10466            (const_string "ishift")))
10467    (set_attr "mode" "DI")])
10469 (define_insn "*ashldi3_cconly_rex64"
10470   [(set (reg FLAGS_REG)
10471         (compare
10472           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10473                      (match_operand:QI 2 "immediate_operand" "e"))
10474           (const_int 0)))
10475    (clobber (match_scratch:DI 0 "=r"))]
10476   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10477    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10478    && (optimize_size
10479        || !TARGET_PARTIAL_FLAG_REG_STALL
10480        || (operands[2] == const1_rtx
10481            && (TARGET_SHIFT1
10482                || TARGET_DOUBLE_WITH_ADD)))"
10484   switch (get_attr_type (insn))
10485     {
10486     case TYPE_ALU:
10487       gcc_assert (operands[2] == const1_rtx);
10488       return "add{q}\t{%0, %0|%0, %0}";
10490     default:
10491       if (REG_P (operands[2]))
10492         return "sal{q}\t{%b2, %0|%0, %b2}";
10493       else if (operands[2] == const1_rtx
10494                && (TARGET_SHIFT1 || optimize_size))
10495         return "sal{q}\t%0";
10496       else
10497         return "sal{q}\t{%2, %0|%0, %2}";
10498     }
10500   [(set (attr "type")
10501      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10502                           (const_int 0))
10503                       (match_operand 0 "register_operand" ""))
10504                  (match_operand 2 "const1_operand" ""))
10505               (const_string "alu")
10506            ]
10507            (const_string "ishift")))
10508    (set_attr "mode" "DI")])
10510 (define_insn "*ashldi3_1"
10511   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10512         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10513                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10514    (clobber (reg:CC FLAGS_REG))]
10515   "!TARGET_64BIT"
10516   "#"
10517   [(set_attr "type" "multi")])
10519 ;; By default we don't ask for a scratch register, because when DImode
10520 ;; values are manipulated, registers are already at a premium.  But if
10521 ;; we have one handy, we won't turn it away.
10522 (define_peephole2
10523   [(match_scratch:SI 3 "r")
10524    (parallel [(set (match_operand:DI 0 "register_operand" "")
10525                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10526                               (match_operand:QI 2 "nonmemory_operand" "")))
10527               (clobber (reg:CC FLAGS_REG))])
10528    (match_dup 3)]
10529   "!TARGET_64BIT && TARGET_CMOVE"
10530   [(const_int 0)]
10531   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10533 (define_split
10534   [(set (match_operand:DI 0 "register_operand" "")
10535         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10536                    (match_operand:QI 2 "nonmemory_operand" "")))
10537    (clobber (reg:CC FLAGS_REG))]
10538   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10539                      ? flow2_completed : reload_completed)"
10540   [(const_int 0)]
10541   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10543 (define_insn "x86_shld_1"
10544   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10545         (ior:SI (ashift:SI (match_dup 0)
10546                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10547                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10548                   (minus:QI (const_int 32) (match_dup 2)))))
10549    (clobber (reg:CC FLAGS_REG))]
10550   ""
10551   "@
10552    shld{l}\t{%2, %1, %0|%0, %1, %2}
10553    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10554   [(set_attr "type" "ishift")
10555    (set_attr "prefix_0f" "1")
10556    (set_attr "mode" "SI")
10557    (set_attr "pent_pair" "np")
10558    (set_attr "athlon_decode" "vector")])
10560 (define_expand "x86_shift_adj_1"
10561   [(set (reg:CCZ FLAGS_REG)
10562         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10563                              (const_int 32))
10564                      (const_int 0)))
10565    (set (match_operand:SI 0 "register_operand" "")
10566         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10567                          (match_operand:SI 1 "register_operand" "")
10568                          (match_dup 0)))
10569    (set (match_dup 1)
10570         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10571                          (match_operand:SI 3 "register_operand" "r")
10572                          (match_dup 1)))]
10573   "TARGET_CMOVE"
10574   "")
10576 (define_expand "x86_shift_adj_2"
10577   [(use (match_operand:SI 0 "register_operand" ""))
10578    (use (match_operand:SI 1 "register_operand" ""))
10579    (use (match_operand:QI 2 "register_operand" ""))]
10580   ""
10582   rtx label = gen_label_rtx ();
10583   rtx tmp;
10585   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10587   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10588   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10589   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10590                               gen_rtx_LABEL_REF (VOIDmode, label),
10591                               pc_rtx);
10592   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10593   JUMP_LABEL (tmp) = label;
10595   emit_move_insn (operands[0], operands[1]);
10596   ix86_expand_clear (operands[1]);
10598   emit_label (label);
10599   LABEL_NUSES (label) = 1;
10601   DONE;
10604 (define_expand "ashlsi3"
10605   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10606         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10607                    (match_operand:QI 2 "nonmemory_operand" "")))
10608    (clobber (reg:CC FLAGS_REG))]
10609   ""
10610   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10612 (define_insn "*ashlsi3_1"
10613   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10614         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10615                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10616    (clobber (reg:CC FLAGS_REG))]
10617   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10619   switch (get_attr_type (insn))
10620     {
10621     case TYPE_ALU:
10622       gcc_assert (operands[2] == const1_rtx);
10623       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10624       return "add{l}\t{%0, %0|%0, %0}";
10626     case TYPE_LEA:
10627       return "#";
10629     default:
10630       if (REG_P (operands[2]))
10631         return "sal{l}\t{%b2, %0|%0, %b2}";
10632       else if (operands[2] == const1_rtx
10633                && (TARGET_SHIFT1 || optimize_size))
10634         return "sal{l}\t%0";
10635       else
10636         return "sal{l}\t{%2, %0|%0, %2}";
10637     }
10639   [(set (attr "type")
10640      (cond [(eq_attr "alternative" "1")
10641               (const_string "lea")
10642             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10643                           (const_int 0))
10644                       (match_operand 0 "register_operand" ""))
10645                  (match_operand 2 "const1_operand" ""))
10646               (const_string "alu")
10647            ]
10648            (const_string "ishift")))
10649    (set_attr "mode" "SI")])
10651 ;; Convert lea to the lea pattern to avoid flags dependency.
10652 (define_split
10653   [(set (match_operand 0 "register_operand" "")
10654         (ashift (match_operand 1 "index_register_operand" "")
10655                 (match_operand:QI 2 "const_int_operand" "")))
10656    (clobber (reg:CC FLAGS_REG))]
10657   "reload_completed
10658    && true_regnum (operands[0]) != true_regnum (operands[1])
10659    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10660   [(const_int 0)]
10662   rtx pat;
10663   enum machine_mode mode = GET_MODE (operands[0]);
10665   if (GET_MODE_SIZE (mode) < 4)
10666     operands[0] = gen_lowpart (SImode, operands[0]);
10667   if (mode != Pmode)
10668     operands[1] = gen_lowpart (Pmode, operands[1]);
10669   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10671   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10672   if (Pmode != SImode)
10673     pat = gen_rtx_SUBREG (SImode, pat, 0);
10674   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10675   DONE;
10678 ;; Rare case of shifting RSP is handled by generating move and shift
10679 (define_split
10680   [(set (match_operand 0 "register_operand" "")
10681         (ashift (match_operand 1 "register_operand" "")
10682                 (match_operand:QI 2 "const_int_operand" "")))
10683    (clobber (reg:CC FLAGS_REG))]
10684   "reload_completed
10685    && true_regnum (operands[0]) != true_regnum (operands[1])"
10686   [(const_int 0)]
10688   rtx pat, clob;
10689   emit_move_insn (operands[0], operands[1]);
10690   pat = gen_rtx_SET (VOIDmode, operands[0],
10691                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10692                                      operands[0], operands[2]));
10693   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10694   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10695   DONE;
10698 (define_insn "*ashlsi3_1_zext"
10699   [(set (match_operand:DI 0 "register_operand" "=r,r")
10700         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10701                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10702    (clobber (reg:CC FLAGS_REG))]
10703   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10705   switch (get_attr_type (insn))
10706     {
10707     case TYPE_ALU:
10708       gcc_assert (operands[2] == const1_rtx);
10709       return "add{l}\t{%k0, %k0|%k0, %k0}";
10711     case TYPE_LEA:
10712       return "#";
10714     default:
10715       if (REG_P (operands[2]))
10716         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10717       else if (operands[2] == const1_rtx
10718                && (TARGET_SHIFT1 || optimize_size))
10719         return "sal{l}\t%k0";
10720       else
10721         return "sal{l}\t{%2, %k0|%k0, %2}";
10722     }
10724   [(set (attr "type")
10725      (cond [(eq_attr "alternative" "1")
10726               (const_string "lea")
10727             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10728                      (const_int 0))
10729                  (match_operand 2 "const1_operand" ""))
10730               (const_string "alu")
10731            ]
10732            (const_string "ishift")))
10733    (set_attr "mode" "SI")])
10735 ;; Convert lea to the lea pattern to avoid flags dependency.
10736 (define_split
10737   [(set (match_operand:DI 0 "register_operand" "")
10738         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10739                                 (match_operand:QI 2 "const_int_operand" ""))))
10740    (clobber (reg:CC FLAGS_REG))]
10741   "TARGET_64BIT && reload_completed
10742    && true_regnum (operands[0]) != true_regnum (operands[1])"
10743   [(set (match_dup 0) (zero_extend:DI
10744                         (subreg:SI (mult:SI (match_dup 1)
10745                                             (match_dup 2)) 0)))]
10747   operands[1] = gen_lowpart (Pmode, operands[1]);
10748   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10751 ;; This pattern can't accept a variable shift count, since shifts by
10752 ;; zero don't affect the flags.  We assume that shifts by constant
10753 ;; zero are optimized away.
10754 (define_insn "*ashlsi3_cmp"
10755   [(set (reg FLAGS_REG)
10756         (compare
10757           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10758                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10759           (const_int 0)))
10760    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10761         (ashift:SI (match_dup 1) (match_dup 2)))]
10762   "ix86_match_ccmode (insn, CCGOCmode)
10763    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10764    && (optimize_size
10765        || !TARGET_PARTIAL_FLAG_REG_STALL
10766        || (operands[2] == const1_rtx
10767            && (TARGET_SHIFT1
10768                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10770   switch (get_attr_type (insn))
10771     {
10772     case TYPE_ALU:
10773       gcc_assert (operands[2] == const1_rtx);
10774       return "add{l}\t{%0, %0|%0, %0}";
10776     default:
10777       if (REG_P (operands[2]))
10778         return "sal{l}\t{%b2, %0|%0, %b2}";
10779       else if (operands[2] == const1_rtx
10780                && (TARGET_SHIFT1 || optimize_size))
10781         return "sal{l}\t%0";
10782       else
10783         return "sal{l}\t{%2, %0|%0, %2}";
10784     }
10786   [(set (attr "type")
10787      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10788                           (const_int 0))
10789                       (match_operand 0 "register_operand" ""))
10790                  (match_operand 2 "const1_operand" ""))
10791               (const_string "alu")
10792            ]
10793            (const_string "ishift")))
10794    (set_attr "mode" "SI")])
10796 (define_insn "*ashlsi3_cconly"
10797   [(set (reg FLAGS_REG)
10798         (compare
10799           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10800                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10801           (const_int 0)))
10802    (clobber (match_scratch:SI 0 "=r"))]
10803   "ix86_match_ccmode (insn, CCGOCmode)
10804    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10805    && (optimize_size
10806        || !TARGET_PARTIAL_FLAG_REG_STALL
10807        || (operands[2] == const1_rtx
10808            && (TARGET_SHIFT1
10809                || TARGET_DOUBLE_WITH_ADD)))"
10811   switch (get_attr_type (insn))
10812     {
10813     case TYPE_ALU:
10814       gcc_assert (operands[2] == const1_rtx);
10815       return "add{l}\t{%0, %0|%0, %0}";
10817     default:
10818       if (REG_P (operands[2]))
10819         return "sal{l}\t{%b2, %0|%0, %b2}";
10820       else if (operands[2] == const1_rtx
10821                && (TARGET_SHIFT1 || optimize_size))
10822         return "sal{l}\t%0";
10823       else
10824         return "sal{l}\t{%2, %0|%0, %2}";
10825     }
10827   [(set (attr "type")
10828      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10829                           (const_int 0))
10830                       (match_operand 0 "register_operand" ""))
10831                  (match_operand 2 "const1_operand" ""))
10832               (const_string "alu")
10833            ]
10834            (const_string "ishift")))
10835    (set_attr "mode" "SI")])
10837 (define_insn "*ashlsi3_cmp_zext"
10838   [(set (reg FLAGS_REG)
10839         (compare
10840           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10841                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10842           (const_int 0)))
10843    (set (match_operand:DI 0 "register_operand" "=r")
10844         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10845   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10846    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10847    && (optimize_size
10848        || !TARGET_PARTIAL_FLAG_REG_STALL
10849        || (operands[2] == const1_rtx
10850            && (TARGET_SHIFT1
10851                || TARGET_DOUBLE_WITH_ADD)))"
10853   switch (get_attr_type (insn))
10854     {
10855     case TYPE_ALU:
10856       gcc_assert (operands[2] == const1_rtx);
10857       return "add{l}\t{%k0, %k0|%k0, %k0}";
10859     default:
10860       if (REG_P (operands[2]))
10861         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10862       else if (operands[2] == const1_rtx
10863                && (TARGET_SHIFT1 || optimize_size))
10864         return "sal{l}\t%k0";
10865       else
10866         return "sal{l}\t{%2, %k0|%k0, %2}";
10867     }
10869   [(set (attr "type")
10870      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10871                      (const_int 0))
10872                  (match_operand 2 "const1_operand" ""))
10873               (const_string "alu")
10874            ]
10875            (const_string "ishift")))
10876    (set_attr "mode" "SI")])
10878 (define_expand "ashlhi3"
10879   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10880         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10881                    (match_operand:QI 2 "nonmemory_operand" "")))
10882    (clobber (reg:CC FLAGS_REG))]
10883   "TARGET_HIMODE_MATH"
10884   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10886 (define_insn "*ashlhi3_1_lea"
10887   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10888         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10889                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10890    (clobber (reg:CC FLAGS_REG))]
10891   "!TARGET_PARTIAL_REG_STALL
10892    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10894   switch (get_attr_type (insn))
10895     {
10896     case TYPE_LEA:
10897       return "#";
10898     case TYPE_ALU:
10899       gcc_assert (operands[2] == const1_rtx);
10900       return "add{w}\t{%0, %0|%0, %0}";
10902     default:
10903       if (REG_P (operands[2]))
10904         return "sal{w}\t{%b2, %0|%0, %b2}";
10905       else if (operands[2] == const1_rtx
10906                && (TARGET_SHIFT1 || optimize_size))
10907         return "sal{w}\t%0";
10908       else
10909         return "sal{w}\t{%2, %0|%0, %2}";
10910     }
10912   [(set (attr "type")
10913      (cond [(eq_attr "alternative" "1")
10914               (const_string "lea")
10915             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10916                           (const_int 0))
10917                       (match_operand 0 "register_operand" ""))
10918                  (match_operand 2 "const1_operand" ""))
10919               (const_string "alu")
10920            ]
10921            (const_string "ishift")))
10922    (set_attr "mode" "HI,SI")])
10924 (define_insn "*ashlhi3_1"
10925   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10926         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10927                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10928    (clobber (reg:CC FLAGS_REG))]
10929   "TARGET_PARTIAL_REG_STALL
10930    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10932   switch (get_attr_type (insn))
10933     {
10934     case TYPE_ALU:
10935       gcc_assert (operands[2] == const1_rtx);
10936       return "add{w}\t{%0, %0|%0, %0}";
10938     default:
10939       if (REG_P (operands[2]))
10940         return "sal{w}\t{%b2, %0|%0, %b2}";
10941       else if (operands[2] == const1_rtx
10942                && (TARGET_SHIFT1 || optimize_size))
10943         return "sal{w}\t%0";
10944       else
10945         return "sal{w}\t{%2, %0|%0, %2}";
10946     }
10948   [(set (attr "type")
10949      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10950                           (const_int 0))
10951                       (match_operand 0 "register_operand" ""))
10952                  (match_operand 2 "const1_operand" ""))
10953               (const_string "alu")
10954            ]
10955            (const_string "ishift")))
10956    (set_attr "mode" "HI")])
10958 ;; This pattern can't accept a variable shift count, since shifts by
10959 ;; zero don't affect the flags.  We assume that shifts by constant
10960 ;; zero are optimized away.
10961 (define_insn "*ashlhi3_cmp"
10962   [(set (reg FLAGS_REG)
10963         (compare
10964           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10965                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10966           (const_int 0)))
10967    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10968         (ashift:HI (match_dup 1) (match_dup 2)))]
10969   "ix86_match_ccmode (insn, CCGOCmode)
10970    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10971    && (optimize_size
10972        || !TARGET_PARTIAL_FLAG_REG_STALL
10973        || (operands[2] == const1_rtx
10974            && (TARGET_SHIFT1
10975                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10977   switch (get_attr_type (insn))
10978     {
10979     case TYPE_ALU:
10980       gcc_assert (operands[2] == const1_rtx);
10981       return "add{w}\t{%0, %0|%0, %0}";
10983     default:
10984       if (REG_P (operands[2]))
10985         return "sal{w}\t{%b2, %0|%0, %b2}";
10986       else if (operands[2] == const1_rtx
10987                && (TARGET_SHIFT1 || optimize_size))
10988         return "sal{w}\t%0";
10989       else
10990         return "sal{w}\t{%2, %0|%0, %2}";
10991     }
10993   [(set (attr "type")
10994      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10995                           (const_int 0))
10996                       (match_operand 0 "register_operand" ""))
10997                  (match_operand 2 "const1_operand" ""))
10998               (const_string "alu")
10999            ]
11000            (const_string "ishift")))
11001    (set_attr "mode" "HI")])
11003 (define_insn "*ashlhi3_cconly"
11004   [(set (reg FLAGS_REG)
11005         (compare
11006           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11007                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11008           (const_int 0)))
11009    (clobber (match_scratch:HI 0 "=r"))]
11010   "ix86_match_ccmode (insn, CCGOCmode)
11011    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11012    && (optimize_size
11013        || !TARGET_PARTIAL_FLAG_REG_STALL
11014        || (operands[2] == const1_rtx
11015            && (TARGET_SHIFT1
11016                || TARGET_DOUBLE_WITH_ADD)))"
11018   switch (get_attr_type (insn))
11019     {
11020     case TYPE_ALU:
11021       gcc_assert (operands[2] == const1_rtx);
11022       return "add{w}\t{%0, %0|%0, %0}";
11024     default:
11025       if (REG_P (operands[2]))
11026         return "sal{w}\t{%b2, %0|%0, %b2}";
11027       else if (operands[2] == const1_rtx
11028                && (TARGET_SHIFT1 || optimize_size))
11029         return "sal{w}\t%0";
11030       else
11031         return "sal{w}\t{%2, %0|%0, %2}";
11032     }
11034   [(set (attr "type")
11035      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11036                           (const_int 0))
11037                       (match_operand 0 "register_operand" ""))
11038                  (match_operand 2 "const1_operand" ""))
11039               (const_string "alu")
11040            ]
11041            (const_string "ishift")))
11042    (set_attr "mode" "HI")])
11044 (define_expand "ashlqi3"
11045   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11046         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11047                    (match_operand:QI 2 "nonmemory_operand" "")))
11048    (clobber (reg:CC FLAGS_REG))]
11049   "TARGET_QIMODE_MATH"
11050   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11052 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11054 (define_insn "*ashlqi3_1_lea"
11055   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11056         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11057                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11058    (clobber (reg:CC FLAGS_REG))]
11059   "!TARGET_PARTIAL_REG_STALL
11060    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11062   switch (get_attr_type (insn))
11063     {
11064     case TYPE_LEA:
11065       return "#";
11066     case TYPE_ALU:
11067       gcc_assert (operands[2] == const1_rtx);
11068       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11069         return "add{l}\t{%k0, %k0|%k0, %k0}";
11070       else
11071         return "add{b}\t{%0, %0|%0, %0}";
11073     default:
11074       if (REG_P (operands[2]))
11075         {
11076           if (get_attr_mode (insn) == MODE_SI)
11077             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11078           else
11079             return "sal{b}\t{%b2, %0|%0, %b2}";
11080         }
11081       else if (operands[2] == const1_rtx
11082                && (TARGET_SHIFT1 || optimize_size))
11083         {
11084           if (get_attr_mode (insn) == MODE_SI)
11085             return "sal{l}\t%0";
11086           else
11087             return "sal{b}\t%0";
11088         }
11089       else
11090         {
11091           if (get_attr_mode (insn) == MODE_SI)
11092             return "sal{l}\t{%2, %k0|%k0, %2}";
11093           else
11094             return "sal{b}\t{%2, %0|%0, %2}";
11095         }
11096     }
11098   [(set (attr "type")
11099      (cond [(eq_attr "alternative" "2")
11100               (const_string "lea")
11101             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11102                           (const_int 0))
11103                       (match_operand 0 "register_operand" ""))
11104                  (match_operand 2 "const1_operand" ""))
11105               (const_string "alu")
11106            ]
11107            (const_string "ishift")))
11108    (set_attr "mode" "QI,SI,SI")])
11110 (define_insn "*ashlqi3_1"
11111   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11112         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11113                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11114    (clobber (reg:CC FLAGS_REG))]
11115   "TARGET_PARTIAL_REG_STALL
11116    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11118   switch (get_attr_type (insn))
11119     {
11120     case TYPE_ALU:
11121       gcc_assert (operands[2] == const1_rtx);
11122       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11123         return "add{l}\t{%k0, %k0|%k0, %k0}";
11124       else
11125         return "add{b}\t{%0, %0|%0, %0}";
11127     default:
11128       if (REG_P (operands[2]))
11129         {
11130           if (get_attr_mode (insn) == MODE_SI)
11131             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11132           else
11133             return "sal{b}\t{%b2, %0|%0, %b2}";
11134         }
11135       else if (operands[2] == const1_rtx
11136                && (TARGET_SHIFT1 || optimize_size))
11137         {
11138           if (get_attr_mode (insn) == MODE_SI)
11139             return "sal{l}\t%0";
11140           else
11141             return "sal{b}\t%0";
11142         }
11143       else
11144         {
11145           if (get_attr_mode (insn) == MODE_SI)
11146             return "sal{l}\t{%2, %k0|%k0, %2}";
11147           else
11148             return "sal{b}\t{%2, %0|%0, %2}";
11149         }
11150     }
11152   [(set (attr "type")
11153      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11154                           (const_int 0))
11155                       (match_operand 0 "register_operand" ""))
11156                  (match_operand 2 "const1_operand" ""))
11157               (const_string "alu")
11158            ]
11159            (const_string "ishift")))
11160    (set_attr "mode" "QI,SI")])
11162 ;; This pattern can't accept a variable shift count, since shifts by
11163 ;; zero don't affect the flags.  We assume that shifts by constant
11164 ;; zero are optimized away.
11165 (define_insn "*ashlqi3_cmp"
11166   [(set (reg FLAGS_REG)
11167         (compare
11168           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11169                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11170           (const_int 0)))
11171    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11172         (ashift:QI (match_dup 1) (match_dup 2)))]
11173   "ix86_match_ccmode (insn, CCGOCmode)
11174    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11175    && (optimize_size
11176        || !TARGET_PARTIAL_FLAG_REG_STALL
11177        || (operands[2] == const1_rtx
11178            && (TARGET_SHIFT1
11179                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11181   switch (get_attr_type (insn))
11182     {
11183     case TYPE_ALU:
11184       gcc_assert (operands[2] == const1_rtx);
11185       return "add{b}\t{%0, %0|%0, %0}";
11187     default:
11188       if (REG_P (operands[2]))
11189         return "sal{b}\t{%b2, %0|%0, %b2}";
11190       else if (operands[2] == const1_rtx
11191                && (TARGET_SHIFT1 || optimize_size))
11192         return "sal{b}\t%0";
11193       else
11194         return "sal{b}\t{%2, %0|%0, %2}";
11195     }
11197   [(set (attr "type")
11198      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11199                           (const_int 0))
11200                       (match_operand 0 "register_operand" ""))
11201                  (match_operand 2 "const1_operand" ""))
11202               (const_string "alu")
11203            ]
11204            (const_string "ishift")))
11205    (set_attr "mode" "QI")])
11207 (define_insn "*ashlqi3_cconly"
11208   [(set (reg FLAGS_REG)
11209         (compare
11210           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11211                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11212           (const_int 0)))
11213    (clobber (match_scratch:QI 0 "=q"))]
11214   "ix86_match_ccmode (insn, CCGOCmode)
11215    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11216    && (optimize_size
11217        || !TARGET_PARTIAL_FLAG_REG_STALL
11218        || (operands[2] == const1_rtx
11219            && (TARGET_SHIFT1
11220                || TARGET_DOUBLE_WITH_ADD)))"
11222   switch (get_attr_type (insn))
11223     {
11224     case TYPE_ALU:
11225       gcc_assert (operands[2] == const1_rtx);
11226       return "add{b}\t{%0, %0|%0, %0}";
11228     default:
11229       if (REG_P (operands[2]))
11230         return "sal{b}\t{%b2, %0|%0, %b2}";
11231       else if (operands[2] == const1_rtx
11232                && (TARGET_SHIFT1 || optimize_size))
11233         return "sal{b}\t%0";
11234       else
11235         return "sal{b}\t{%2, %0|%0, %2}";
11236     }
11238   [(set (attr "type")
11239      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11240                           (const_int 0))
11241                       (match_operand 0 "register_operand" ""))
11242                  (match_operand 2 "const1_operand" ""))
11243               (const_string "alu")
11244            ]
11245            (const_string "ishift")))
11246    (set_attr "mode" "QI")])
11248 ;; See comment above `ashldi3' about how this works.
11250 (define_expand "ashrti3"
11251   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11252                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11253                                 (match_operand:QI 2 "nonmemory_operand" "")))
11254               (clobber (reg:CC FLAGS_REG))])]
11255   "TARGET_64BIT"
11257   if (! immediate_operand (operands[2], QImode))
11258     {
11259       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11260       DONE;
11261     }
11262   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11263   DONE;
11266 (define_insn "ashrti3_1"
11267   [(set (match_operand:TI 0 "register_operand" "=r")
11268         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11269                      (match_operand:QI 2 "register_operand" "c")))
11270    (clobber (match_scratch:DI 3 "=&r"))
11271    (clobber (reg:CC FLAGS_REG))]
11272   "TARGET_64BIT"
11273   "#"
11274   [(set_attr "type" "multi")])
11276 (define_insn "*ashrti3_2"
11277   [(set (match_operand:TI 0 "register_operand" "=r")
11278         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11279                      (match_operand:QI 2 "immediate_operand" "O")))
11280    (clobber (reg:CC FLAGS_REG))]
11281   "TARGET_64BIT"
11282   "#"
11283   [(set_attr "type" "multi")])
11285 (define_split
11286   [(set (match_operand:TI 0 "register_operand" "")
11287         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11288                      (match_operand:QI 2 "register_operand" "")))
11289    (clobber (match_scratch:DI 3 ""))
11290    (clobber (reg:CC FLAGS_REG))]
11291   "TARGET_64BIT && reload_completed"
11292   [(const_int 0)]
11293   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11295 (define_split
11296   [(set (match_operand:TI 0 "register_operand" "")
11297         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11298                      (match_operand:QI 2 "immediate_operand" "")))
11299    (clobber (reg:CC FLAGS_REG))]
11300   "TARGET_64BIT && reload_completed"
11301   [(const_int 0)]
11302   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11304 (define_insn "x86_64_shrd"
11305   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11306         (ior:DI (ashiftrt:DI (match_dup 0)
11307                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11308                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11309                   (minus:QI (const_int 64) (match_dup 2)))))
11310    (clobber (reg:CC FLAGS_REG))]
11311   "TARGET_64BIT"
11312   "@
11313    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11314    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11315   [(set_attr "type" "ishift")
11316    (set_attr "prefix_0f" "1")
11317    (set_attr "mode" "DI")
11318    (set_attr "athlon_decode" "vector")])
11320 (define_expand "ashrdi3"
11321   [(set (match_operand:DI 0 "shiftdi_operand" "")
11322         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11323                      (match_operand:QI 2 "nonmemory_operand" "")))]
11324   ""
11325   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11327 (define_insn "*ashrdi3_63_rex64"
11328   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11329         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11330                      (match_operand:DI 2 "const_int_operand" "i,i")))
11331    (clobber (reg:CC FLAGS_REG))]
11332   "TARGET_64BIT && INTVAL (operands[2]) == 63
11333    && (TARGET_USE_CLTD || optimize_size)
11334    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11335   "@
11336    {cqto|cqo}
11337    sar{q}\t{%2, %0|%0, %2}"
11338   [(set_attr "type" "imovx,ishift")
11339    (set_attr "prefix_0f" "0,*")
11340    (set_attr "length_immediate" "0,*")
11341    (set_attr "modrm" "0,1")
11342    (set_attr "mode" "DI")])
11344 (define_insn "*ashrdi3_1_one_bit_rex64"
11345   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11346         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11347                      (match_operand:QI 2 "const1_operand" "")))
11348    (clobber (reg:CC FLAGS_REG))]
11349   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11350    && (TARGET_SHIFT1 || optimize_size)"
11351   "sar{q}\t%0"
11352   [(set_attr "type" "ishift")
11353    (set (attr "length")
11354      (if_then_else (match_operand:DI 0 "register_operand" "")
11355         (const_string "2")
11356         (const_string "*")))])
11358 (define_insn "*ashrdi3_1_rex64"
11359   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11360         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11361                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11362    (clobber (reg:CC FLAGS_REG))]
11363   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11364   "@
11365    sar{q}\t{%2, %0|%0, %2}
11366    sar{q}\t{%b2, %0|%0, %b2}"
11367   [(set_attr "type" "ishift")
11368    (set_attr "mode" "DI")])
11370 ;; This pattern can't accept a variable shift count, since shifts by
11371 ;; zero don't affect the flags.  We assume that shifts by constant
11372 ;; zero are optimized away.
11373 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11374   [(set (reg FLAGS_REG)
11375         (compare
11376           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11377                        (match_operand:QI 2 "const1_operand" ""))
11378           (const_int 0)))
11379    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11380         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11381   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11382    && (TARGET_SHIFT1 || optimize_size)
11383    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11384   "sar{q}\t%0"
11385   [(set_attr "type" "ishift")
11386    (set (attr "length")
11387      (if_then_else (match_operand:DI 0 "register_operand" "")
11388         (const_string "2")
11389         (const_string "*")))])
11391 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11392   [(set (reg FLAGS_REG)
11393         (compare
11394           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11395                        (match_operand:QI 2 "const1_operand" ""))
11396           (const_int 0)))
11397    (clobber (match_scratch:DI 0 "=r"))]
11398   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11399    && (TARGET_SHIFT1 || optimize_size)
11400    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11401   "sar{q}\t%0"
11402   [(set_attr "type" "ishift")
11403    (set_attr "length" "2")])
11405 ;; This pattern can't accept a variable shift count, since shifts by
11406 ;; zero don't affect the flags.  We assume that shifts by constant
11407 ;; zero are optimized away.
11408 (define_insn "*ashrdi3_cmp_rex64"
11409   [(set (reg FLAGS_REG)
11410         (compare
11411           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412                        (match_operand:QI 2 "const_int_operand" "n"))
11413           (const_int 0)))
11414    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11415         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11416   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11417    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11418    && (optimize_size
11419        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11420   "sar{q}\t{%2, %0|%0, %2}"
11421   [(set_attr "type" "ishift")
11422    (set_attr "mode" "DI")])
11424 (define_insn "*ashrdi3_cconly_rex64"
11425   [(set (reg FLAGS_REG)
11426         (compare
11427           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11428                        (match_operand:QI 2 "const_int_operand" "n"))
11429           (const_int 0)))
11430    (clobber (match_scratch:DI 0 "=r"))]
11431   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11432    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11433    && (optimize_size
11434        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11435   "sar{q}\t{%2, %0|%0, %2}"
11436   [(set_attr "type" "ishift")
11437    (set_attr "mode" "DI")])
11439 (define_insn "*ashrdi3_1"
11440   [(set (match_operand:DI 0 "register_operand" "=r")
11441         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11442                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11443    (clobber (reg:CC FLAGS_REG))]
11444   "!TARGET_64BIT"
11445   "#"
11446   [(set_attr "type" "multi")])
11448 ;; By default we don't ask for a scratch register, because when DImode
11449 ;; values are manipulated, registers are already at a premium.  But if
11450 ;; we have one handy, we won't turn it away.
11451 (define_peephole2
11452   [(match_scratch:SI 3 "r")
11453    (parallel [(set (match_operand:DI 0 "register_operand" "")
11454                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11455                                 (match_operand:QI 2 "nonmemory_operand" "")))
11456               (clobber (reg:CC FLAGS_REG))])
11457    (match_dup 3)]
11458   "!TARGET_64BIT && TARGET_CMOVE"
11459   [(const_int 0)]
11460   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11462 (define_split
11463   [(set (match_operand:DI 0 "register_operand" "")
11464         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11465                      (match_operand:QI 2 "nonmemory_operand" "")))
11466    (clobber (reg:CC FLAGS_REG))]
11467   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11468                      ? flow2_completed : reload_completed)"
11469   [(const_int 0)]
11470   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11472 (define_insn "x86_shrd_1"
11473   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11474         (ior:SI (ashiftrt:SI (match_dup 0)
11475                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11476                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11477                   (minus:QI (const_int 32) (match_dup 2)))))
11478    (clobber (reg:CC FLAGS_REG))]
11479   ""
11480   "@
11481    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11482    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11483   [(set_attr "type" "ishift")
11484    (set_attr "prefix_0f" "1")
11485    (set_attr "pent_pair" "np")
11486    (set_attr "mode" "SI")])
11488 (define_expand "x86_shift_adj_3"
11489   [(use (match_operand:SI 0 "register_operand" ""))
11490    (use (match_operand:SI 1 "register_operand" ""))
11491    (use (match_operand:QI 2 "register_operand" ""))]
11492   ""
11494   rtx label = gen_label_rtx ();
11495   rtx tmp;
11497   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11499   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11500   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11501   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11502                               gen_rtx_LABEL_REF (VOIDmode, label),
11503                               pc_rtx);
11504   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11505   JUMP_LABEL (tmp) = label;
11507   emit_move_insn (operands[0], operands[1]);
11508   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11510   emit_label (label);
11511   LABEL_NUSES (label) = 1;
11513   DONE;
11516 (define_insn "ashrsi3_31"
11517   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11518         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11519                      (match_operand:SI 2 "const_int_operand" "i,i")))
11520    (clobber (reg:CC FLAGS_REG))]
11521   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11522    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11523   "@
11524    {cltd|cdq}
11525    sar{l}\t{%2, %0|%0, %2}"
11526   [(set_attr "type" "imovx,ishift")
11527    (set_attr "prefix_0f" "0,*")
11528    (set_attr "length_immediate" "0,*")
11529    (set_attr "modrm" "0,1")
11530    (set_attr "mode" "SI")])
11532 (define_insn "*ashrsi3_31_zext"
11533   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11534         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11535                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11536    (clobber (reg:CC FLAGS_REG))]
11537   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11538    && INTVAL (operands[2]) == 31
11539    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11540   "@
11541    {cltd|cdq}
11542    sar{l}\t{%2, %k0|%k0, %2}"
11543   [(set_attr "type" "imovx,ishift")
11544    (set_attr "prefix_0f" "0,*")
11545    (set_attr "length_immediate" "0,*")
11546    (set_attr "modrm" "0,1")
11547    (set_attr "mode" "SI")])
11549 (define_expand "ashrsi3"
11550   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11551         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11552                      (match_operand:QI 2 "nonmemory_operand" "")))
11553    (clobber (reg:CC FLAGS_REG))]
11554   ""
11555   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11557 (define_insn "*ashrsi3_1_one_bit"
11558   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11559         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11560                      (match_operand:QI 2 "const1_operand" "")))
11561    (clobber (reg:CC FLAGS_REG))]
11562   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11563    && (TARGET_SHIFT1 || optimize_size)"
11564   "sar{l}\t%0"
11565   [(set_attr "type" "ishift")
11566    (set (attr "length")
11567      (if_then_else (match_operand:SI 0 "register_operand" "")
11568         (const_string "2")
11569         (const_string "*")))])
11571 (define_insn "*ashrsi3_1_one_bit_zext"
11572   [(set (match_operand:DI 0 "register_operand" "=r")
11573         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11574                                      (match_operand:QI 2 "const1_operand" ""))))
11575    (clobber (reg:CC FLAGS_REG))]
11576   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11577    && (TARGET_SHIFT1 || optimize_size)"
11578   "sar{l}\t%k0"
11579   [(set_attr "type" "ishift")
11580    (set_attr "length" "2")])
11582 (define_insn "*ashrsi3_1"
11583   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11584         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11585                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11586    (clobber (reg:CC FLAGS_REG))]
11587   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11588   "@
11589    sar{l}\t{%2, %0|%0, %2}
11590    sar{l}\t{%b2, %0|%0, %b2}"
11591   [(set_attr "type" "ishift")
11592    (set_attr "mode" "SI")])
11594 (define_insn "*ashrsi3_1_zext"
11595   [(set (match_operand:DI 0 "register_operand" "=r,r")
11596         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11597                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11598    (clobber (reg:CC FLAGS_REG))]
11599   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11600   "@
11601    sar{l}\t{%2, %k0|%k0, %2}
11602    sar{l}\t{%b2, %k0|%k0, %b2}"
11603   [(set_attr "type" "ishift")
11604    (set_attr "mode" "SI")])
11606 ;; This pattern can't accept a variable shift count, since shifts by
11607 ;; zero don't affect the flags.  We assume that shifts by constant
11608 ;; zero are optimized away.
11609 (define_insn "*ashrsi3_one_bit_cmp"
11610   [(set (reg FLAGS_REG)
11611         (compare
11612           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11613                        (match_operand:QI 2 "const1_operand" ""))
11614           (const_int 0)))
11615    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11616         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11617   "ix86_match_ccmode (insn, CCGOCmode)
11618    && (TARGET_SHIFT1 || optimize_size)
11619    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11620   "sar{l}\t%0"
11621   [(set_attr "type" "ishift")
11622    (set (attr "length")
11623      (if_then_else (match_operand:SI 0 "register_operand" "")
11624         (const_string "2")
11625         (const_string "*")))])
11627 (define_insn "*ashrsi3_one_bit_cconly"
11628   [(set (reg FLAGS_REG)
11629         (compare
11630           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11631                        (match_operand:QI 2 "const1_operand" ""))
11632           (const_int 0)))
11633    (clobber (match_scratch:SI 0 "=r"))]
11634   "ix86_match_ccmode (insn, CCGOCmode)
11635    && (TARGET_SHIFT1 || optimize_size)
11636    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11637   "sar{l}\t%0"
11638   [(set_attr "type" "ishift")
11639    (set_attr "length" "2")])
11641 (define_insn "*ashrsi3_one_bit_cmp_zext"
11642   [(set (reg FLAGS_REG)
11643         (compare
11644           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11645                        (match_operand:QI 2 "const1_operand" ""))
11646           (const_int 0)))
11647    (set (match_operand:DI 0 "register_operand" "=r")
11648         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11649   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11650    && (TARGET_SHIFT1 || optimize_size)
11651    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11652   "sar{l}\t%k0"
11653   [(set_attr "type" "ishift")
11654    (set_attr "length" "2")])
11656 ;; This pattern can't accept a variable shift count, since shifts by
11657 ;; zero don't affect the flags.  We assume that shifts by constant
11658 ;; zero are optimized away.
11659 (define_insn "*ashrsi3_cmp"
11660   [(set (reg FLAGS_REG)
11661         (compare
11662           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11663                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11664           (const_int 0)))
11665    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11666         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11667   "ix86_match_ccmode (insn, CCGOCmode)
11668    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11669    && (optimize_size
11670        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11671   "sar{l}\t{%2, %0|%0, %2}"
11672   [(set_attr "type" "ishift")
11673    (set_attr "mode" "SI")])
11675 (define_insn "*ashrsi3_cconly"
11676   [(set (reg FLAGS_REG)
11677         (compare
11678           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11679                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11680           (const_int 0)))
11681    (clobber (match_scratch:SI 0 "=r"))]
11682   "ix86_match_ccmode (insn, CCGOCmode)
11683    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11684    && (optimize_size
11685        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11686   "sar{l}\t{%2, %0|%0, %2}"
11687   [(set_attr "type" "ishift")
11688    (set_attr "mode" "SI")])
11690 (define_insn "*ashrsi3_cmp_zext"
11691   [(set (reg FLAGS_REG)
11692         (compare
11693           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11694                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11695           (const_int 0)))
11696    (set (match_operand:DI 0 "register_operand" "=r")
11697         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11698   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11699    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11700    && (optimize_size
11701        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11702   "sar{l}\t{%2, %k0|%k0, %2}"
11703   [(set_attr "type" "ishift")
11704    (set_attr "mode" "SI")])
11706 (define_expand "ashrhi3"
11707   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11708         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11709                      (match_operand:QI 2 "nonmemory_operand" "")))
11710    (clobber (reg:CC FLAGS_REG))]
11711   "TARGET_HIMODE_MATH"
11712   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11714 (define_insn "*ashrhi3_1_one_bit"
11715   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11716         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11717                      (match_operand:QI 2 "const1_operand" "")))
11718    (clobber (reg:CC FLAGS_REG))]
11719   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11720    && (TARGET_SHIFT1 || optimize_size)"
11721   "sar{w}\t%0"
11722   [(set_attr "type" "ishift")
11723    (set (attr "length")
11724      (if_then_else (match_operand 0 "register_operand" "")
11725         (const_string "2")
11726         (const_string "*")))])
11728 (define_insn "*ashrhi3_1"
11729   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11730         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11731                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11732    (clobber (reg:CC FLAGS_REG))]
11733   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11734   "@
11735    sar{w}\t{%2, %0|%0, %2}
11736    sar{w}\t{%b2, %0|%0, %b2}"
11737   [(set_attr "type" "ishift")
11738    (set_attr "mode" "HI")])
11740 ;; This pattern can't accept a variable shift count, since shifts by
11741 ;; zero don't affect the flags.  We assume that shifts by constant
11742 ;; zero are optimized away.
11743 (define_insn "*ashrhi3_one_bit_cmp"
11744   [(set (reg FLAGS_REG)
11745         (compare
11746           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11747                        (match_operand:QI 2 "const1_operand" ""))
11748           (const_int 0)))
11749    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11750         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11751   "ix86_match_ccmode (insn, CCGOCmode)
11752    && (TARGET_SHIFT1 || optimize_size)
11753    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11754   "sar{w}\t%0"
11755   [(set_attr "type" "ishift")
11756    (set (attr "length")
11757      (if_then_else (match_operand 0 "register_operand" "")
11758         (const_string "2")
11759         (const_string "*")))])
11761 (define_insn "*ashrhi3_one_bit_cconly"
11762   [(set (reg FLAGS_REG)
11763         (compare
11764           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11765                        (match_operand:QI 2 "const1_operand" ""))
11766           (const_int 0)))
11767    (clobber (match_scratch:HI 0 "=r"))]
11768   "ix86_match_ccmode (insn, CCGOCmode)
11769    && (TARGET_SHIFT1 || optimize_size)
11770    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11771   "sar{w}\t%0"
11772   [(set_attr "type" "ishift")
11773    (set_attr "length" "2")])
11775 ;; This pattern can't accept a variable shift count, since shifts by
11776 ;; zero don't affect the flags.  We assume that shifts by constant
11777 ;; zero are optimized away.
11778 (define_insn "*ashrhi3_cmp"
11779   [(set (reg FLAGS_REG)
11780         (compare
11781           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11783           (const_int 0)))
11784    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11785         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11786   "ix86_match_ccmode (insn, CCGOCmode)
11787    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11788    && (optimize_size
11789        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11790   "sar{w}\t{%2, %0|%0, %2}"
11791   [(set_attr "type" "ishift")
11792    (set_attr "mode" "HI")])
11794 (define_insn "*ashrhi3_cconly"
11795   [(set (reg FLAGS_REG)
11796         (compare
11797           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11798                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11799           (const_int 0)))
11800    (clobber (match_scratch:HI 0 "=r"))]
11801   "ix86_match_ccmode (insn, CCGOCmode)
11802    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11803    && (optimize_size
11804        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11805   "sar{w}\t{%2, %0|%0, %2}"
11806   [(set_attr "type" "ishift")
11807    (set_attr "mode" "HI")])
11809 (define_expand "ashrqi3"
11810   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11811         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11812                      (match_operand:QI 2 "nonmemory_operand" "")))
11813    (clobber (reg:CC FLAGS_REG))]
11814   "TARGET_QIMODE_MATH"
11815   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11817 (define_insn "*ashrqi3_1_one_bit"
11818   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11819         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11820                      (match_operand:QI 2 "const1_operand" "")))
11821    (clobber (reg:CC FLAGS_REG))]
11822   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11823    && (TARGET_SHIFT1 || optimize_size)"
11824   "sar{b}\t%0"
11825   [(set_attr "type" "ishift")
11826    (set (attr "length")
11827      (if_then_else (match_operand 0 "register_operand" "")
11828         (const_string "2")
11829         (const_string "*")))])
11831 (define_insn "*ashrqi3_1_one_bit_slp"
11832   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11833         (ashiftrt:QI (match_dup 0)
11834                      (match_operand:QI 1 "const1_operand" "")))
11835    (clobber (reg:CC FLAGS_REG))]
11836   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11837    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11838    && (TARGET_SHIFT1 || optimize_size)"
11839   "sar{b}\t%0"
11840   [(set_attr "type" "ishift1")
11841    (set (attr "length")
11842      (if_then_else (match_operand 0 "register_operand" "")
11843         (const_string "2")
11844         (const_string "*")))])
11846 (define_insn "*ashrqi3_1"
11847   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11848         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11849                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11850    (clobber (reg:CC FLAGS_REG))]
11851   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11852   "@
11853    sar{b}\t{%2, %0|%0, %2}
11854    sar{b}\t{%b2, %0|%0, %b2}"
11855   [(set_attr "type" "ishift")
11856    (set_attr "mode" "QI")])
11858 (define_insn "*ashrqi3_1_slp"
11859   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11860         (ashiftrt:QI (match_dup 0)
11861                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11862    (clobber (reg:CC FLAGS_REG))]
11863   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11864    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11865   "@
11866    sar{b}\t{%1, %0|%0, %1}
11867    sar{b}\t{%b1, %0|%0, %b1}"
11868   [(set_attr "type" "ishift1")
11869    (set_attr "mode" "QI")])
11871 ;; This pattern can't accept a variable shift count, since shifts by
11872 ;; zero don't affect the flags.  We assume that shifts by constant
11873 ;; zero are optimized away.
11874 (define_insn "*ashrqi3_one_bit_cmp"
11875   [(set (reg FLAGS_REG)
11876         (compare
11877           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11878                        (match_operand:QI 2 "const1_operand" "I"))
11879           (const_int 0)))
11880    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11881         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11882   "ix86_match_ccmode (insn, CCGOCmode)
11883    && (TARGET_SHIFT1 || optimize_size)
11884    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11885   "sar{b}\t%0"
11886   [(set_attr "type" "ishift")
11887    (set (attr "length")
11888      (if_then_else (match_operand 0 "register_operand" "")
11889         (const_string "2")
11890         (const_string "*")))])
11892 (define_insn "*ashrqi3_one_bit_cconly"
11893   [(set (reg FLAGS_REG)
11894         (compare
11895           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11896                        (match_operand:QI 2 "const1_operand" "I"))
11897           (const_int 0)))
11898    (clobber (match_scratch:QI 0 "=q"))]
11899   "ix86_match_ccmode (insn, CCGOCmode)
11900    && (TARGET_SHIFT1 || optimize_size)
11901    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11902   "sar{b}\t%0"
11903   [(set_attr "type" "ishift")
11904    (set_attr "length" "2")])
11906 ;; This pattern can't accept a variable shift count, since shifts by
11907 ;; zero don't affect the flags.  We assume that shifts by constant
11908 ;; zero are optimized away.
11909 (define_insn "*ashrqi3_cmp"
11910   [(set (reg FLAGS_REG)
11911         (compare
11912           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11913                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11914           (const_int 0)))
11915    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11916         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11917   "ix86_match_ccmode (insn, CCGOCmode)
11918    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11919    && (optimize_size
11920        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11921   "sar{b}\t{%2, %0|%0, %2}"
11922   [(set_attr "type" "ishift")
11923    (set_attr "mode" "QI")])
11925 (define_insn "*ashrqi3_cconly"
11926   [(set (reg FLAGS_REG)
11927         (compare
11928           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11929                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11930           (const_int 0)))
11931    (clobber (match_scratch:QI 0 "=q"))]
11932   "ix86_match_ccmode (insn, CCGOCmode)
11933    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11934    && (optimize_size
11935        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11936   "sar{b}\t{%2, %0|%0, %2}"
11937   [(set_attr "type" "ishift")
11938    (set_attr "mode" "QI")])
11941 ;; Logical shift instructions
11943 ;; See comment above `ashldi3' about how this works.
11945 (define_expand "lshrti3"
11946   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11947                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11948                                 (match_operand:QI 2 "nonmemory_operand" "")))
11949               (clobber (reg:CC FLAGS_REG))])]
11950   "TARGET_64BIT"
11952   if (! immediate_operand (operands[2], QImode))
11953     {
11954       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11955       DONE;
11956     }
11957   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11958   DONE;
11961 (define_insn "lshrti3_1"
11962   [(set (match_operand:TI 0 "register_operand" "=r")
11963         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11964                      (match_operand:QI 2 "register_operand" "c")))
11965    (clobber (match_scratch:DI 3 "=&r"))
11966    (clobber (reg:CC FLAGS_REG))]
11967   "TARGET_64BIT"
11968   "#"
11969   [(set_attr "type" "multi")])
11971 (define_insn "*lshrti3_2"
11972   [(set (match_operand:TI 0 "register_operand" "=r")
11973         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11974                      (match_operand:QI 2 "immediate_operand" "O")))
11975    (clobber (reg:CC FLAGS_REG))]
11976   "TARGET_64BIT"
11977   "#"
11978   [(set_attr "type" "multi")])
11980 (define_split
11981   [(set (match_operand:TI 0 "register_operand" "")
11982         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11983                      (match_operand:QI 2 "register_operand" "")))
11984    (clobber (match_scratch:DI 3 ""))
11985    (clobber (reg:CC FLAGS_REG))]
11986   "TARGET_64BIT && reload_completed"
11987   [(const_int 0)]
11988   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11990 (define_split
11991   [(set (match_operand:TI 0 "register_operand" "")
11992         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11993                      (match_operand:QI 2 "immediate_operand" "")))
11994    (clobber (reg:CC FLAGS_REG))]
11995   "TARGET_64BIT && reload_completed"
11996   [(const_int 0)]
11997   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11999 (define_expand "lshrdi3"
12000   [(set (match_operand:DI 0 "shiftdi_operand" "")
12001         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12002                      (match_operand:QI 2 "nonmemory_operand" "")))]
12003   ""
12004   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12006 (define_insn "*lshrdi3_1_one_bit_rex64"
12007   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12008         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12009                      (match_operand:QI 2 "const1_operand" "")))
12010    (clobber (reg:CC FLAGS_REG))]
12011   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12012    && (TARGET_SHIFT1 || optimize_size)"
12013   "shr{q}\t%0"
12014   [(set_attr "type" "ishift")
12015    (set (attr "length")
12016      (if_then_else (match_operand:DI 0 "register_operand" "")
12017         (const_string "2")
12018         (const_string "*")))])
12020 (define_insn "*lshrdi3_1_rex64"
12021   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12022         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12023                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12024    (clobber (reg:CC FLAGS_REG))]
12025   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12026   "@
12027    shr{q}\t{%2, %0|%0, %2}
12028    shr{q}\t{%b2, %0|%0, %b2}"
12029   [(set_attr "type" "ishift")
12030    (set_attr "mode" "DI")])
12032 ;; This pattern can't accept a variable shift count, since shifts by
12033 ;; zero don't affect the flags.  We assume that shifts by constant
12034 ;; zero are optimized away.
12035 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12036   [(set (reg FLAGS_REG)
12037         (compare
12038           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12039                        (match_operand:QI 2 "const1_operand" ""))
12040           (const_int 0)))
12041    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12042         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12043   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12044    && (TARGET_SHIFT1 || optimize_size)
12045    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12046   "shr{q}\t%0"
12047   [(set_attr "type" "ishift")
12048    (set (attr "length")
12049      (if_then_else (match_operand:DI 0 "register_operand" "")
12050         (const_string "2")
12051         (const_string "*")))])
12053 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12054   [(set (reg FLAGS_REG)
12055         (compare
12056           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12057                        (match_operand:QI 2 "const1_operand" ""))
12058           (const_int 0)))
12059    (clobber (match_scratch:DI 0 "=r"))]
12060   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12061    && (TARGET_SHIFT1 || optimize_size)
12062    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12063   "shr{q}\t%0"
12064   [(set_attr "type" "ishift")
12065    (set_attr "length" "2")])
12067 ;; This pattern can't accept a variable shift count, since shifts by
12068 ;; zero don't affect the flags.  We assume that shifts by constant
12069 ;; zero are optimized away.
12070 (define_insn "*lshrdi3_cmp_rex64"
12071   [(set (reg FLAGS_REG)
12072         (compare
12073           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074                        (match_operand:QI 2 "const_int_operand" "e"))
12075           (const_int 0)))
12076    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12077         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12078   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12079    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12080    && (optimize_size
12081        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12082   "shr{q}\t{%2, %0|%0, %2}"
12083   [(set_attr "type" "ishift")
12084    (set_attr "mode" "DI")])
12086 (define_insn "*lshrdi3_cconly_rex64"
12087   [(set (reg FLAGS_REG)
12088         (compare
12089           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12090                        (match_operand:QI 2 "const_int_operand" "e"))
12091           (const_int 0)))
12092    (clobber (match_scratch:DI 0 "=r"))]
12093   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12094    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12095    && (optimize_size
12096        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12097   "shr{q}\t{%2, %0|%0, %2}"
12098   [(set_attr "type" "ishift")
12099    (set_attr "mode" "DI")])
12101 (define_insn "*lshrdi3_1"
12102   [(set (match_operand:DI 0 "register_operand" "=r")
12103         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12104                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12105    (clobber (reg:CC FLAGS_REG))]
12106   "!TARGET_64BIT"
12107   "#"
12108   [(set_attr "type" "multi")])
12110 ;; By default we don't ask for a scratch register, because when DImode
12111 ;; values are manipulated, registers are already at a premium.  But if
12112 ;; we have one handy, we won't turn it away.
12113 (define_peephole2
12114   [(match_scratch:SI 3 "r")
12115    (parallel [(set (match_operand:DI 0 "register_operand" "")
12116                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12117                                 (match_operand:QI 2 "nonmemory_operand" "")))
12118               (clobber (reg:CC FLAGS_REG))])
12119    (match_dup 3)]
12120   "!TARGET_64BIT && TARGET_CMOVE"
12121   [(const_int 0)]
12122   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12124 (define_split
12125   [(set (match_operand:DI 0 "register_operand" "")
12126         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12127                      (match_operand:QI 2 "nonmemory_operand" "")))
12128    (clobber (reg:CC FLAGS_REG))]
12129   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12130                      ? flow2_completed : reload_completed)"
12131   [(const_int 0)]
12132   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12134 (define_expand "lshrsi3"
12135   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12136         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12137                      (match_operand:QI 2 "nonmemory_operand" "")))
12138    (clobber (reg:CC FLAGS_REG))]
12139   ""
12140   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12142 (define_insn "*lshrsi3_1_one_bit"
12143   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12144         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12145                      (match_operand:QI 2 "const1_operand" "")))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12148    && (TARGET_SHIFT1 || optimize_size)"
12149   "shr{l}\t%0"
12150   [(set_attr "type" "ishift")
12151    (set (attr "length")
12152      (if_then_else (match_operand:SI 0 "register_operand" "")
12153         (const_string "2")
12154         (const_string "*")))])
12156 (define_insn "*lshrsi3_1_one_bit_zext"
12157   [(set (match_operand:DI 0 "register_operand" "=r")
12158         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12159                      (match_operand:QI 2 "const1_operand" "")))
12160    (clobber (reg:CC FLAGS_REG))]
12161   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12162    && (TARGET_SHIFT1 || optimize_size)"
12163   "shr{l}\t%k0"
12164   [(set_attr "type" "ishift")
12165    (set_attr "length" "2")])
12167 (define_insn "*lshrsi3_1"
12168   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12169         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12170                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12171    (clobber (reg:CC FLAGS_REG))]
12172   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12173   "@
12174    shr{l}\t{%2, %0|%0, %2}
12175    shr{l}\t{%b2, %0|%0, %b2}"
12176   [(set_attr "type" "ishift")
12177    (set_attr "mode" "SI")])
12179 (define_insn "*lshrsi3_1_zext"
12180   [(set (match_operand:DI 0 "register_operand" "=r,r")
12181         (zero_extend:DI
12182           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12183                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12184    (clobber (reg:CC FLAGS_REG))]
12185   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12186   "@
12187    shr{l}\t{%2, %k0|%k0, %2}
12188    shr{l}\t{%b2, %k0|%k0, %b2}"
12189   [(set_attr "type" "ishift")
12190    (set_attr "mode" "SI")])
12192 ;; This pattern can't accept a variable shift count, since shifts by
12193 ;; zero don't affect the flags.  We assume that shifts by constant
12194 ;; zero are optimized away.
12195 (define_insn "*lshrsi3_one_bit_cmp"
12196   [(set (reg FLAGS_REG)
12197         (compare
12198           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12199                        (match_operand:QI 2 "const1_operand" ""))
12200           (const_int 0)))
12201    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12202         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12203   "ix86_match_ccmode (insn, CCGOCmode)
12204    && (TARGET_SHIFT1 || optimize_size)
12205    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12206   "shr{l}\t%0"
12207   [(set_attr "type" "ishift")
12208    (set (attr "length")
12209      (if_then_else (match_operand:SI 0 "register_operand" "")
12210         (const_string "2")
12211         (const_string "*")))])
12213 (define_insn "*lshrsi3_one_bit_cconly"
12214   [(set (reg FLAGS_REG)
12215         (compare
12216           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12217                        (match_operand:QI 2 "const1_operand" ""))
12218           (const_int 0)))
12219    (clobber (match_scratch:SI 0 "=r"))]
12220   "ix86_match_ccmode (insn, CCGOCmode)
12221    && (TARGET_SHIFT1 || optimize_size)
12222    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12223   "shr{l}\t%0"
12224   [(set_attr "type" "ishift")
12225    (set_attr "length" "2")])
12227 (define_insn "*lshrsi3_cmp_one_bit_zext"
12228   [(set (reg FLAGS_REG)
12229         (compare
12230           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12231                        (match_operand:QI 2 "const1_operand" ""))
12232           (const_int 0)))
12233    (set (match_operand:DI 0 "register_operand" "=r")
12234         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12235   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12236    && (TARGET_SHIFT1 || optimize_size)
12237    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12238   "shr{l}\t%k0"
12239   [(set_attr "type" "ishift")
12240    (set_attr "length" "2")])
12242 ;; This pattern can't accept a variable shift count, since shifts by
12243 ;; zero don't affect the flags.  We assume that shifts by constant
12244 ;; zero are optimized away.
12245 (define_insn "*lshrsi3_cmp"
12246   [(set (reg FLAGS_REG)
12247         (compare
12248           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12249                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12250           (const_int 0)))
12251    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12252         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12253   "ix86_match_ccmode (insn, CCGOCmode)
12254    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12255    && (optimize_size
12256        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12257   "shr{l}\t{%2, %0|%0, %2}"
12258   [(set_attr "type" "ishift")
12259    (set_attr "mode" "SI")])
12261 (define_insn "*lshrsi3_cconly"
12262   [(set (reg FLAGS_REG)
12263       (compare
12264         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12265                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12266         (const_int 0)))
12267    (clobber (match_scratch:SI 0 "=r"))]
12268   "ix86_match_ccmode (insn, CCGOCmode)
12269    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12270    && (optimize_size
12271        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12272   "shr{l}\t{%2, %0|%0, %2}"
12273   [(set_attr "type" "ishift")
12274    (set_attr "mode" "SI")])
12276 (define_insn "*lshrsi3_cmp_zext"
12277   [(set (reg FLAGS_REG)
12278         (compare
12279           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12280                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12281           (const_int 0)))
12282    (set (match_operand:DI 0 "register_operand" "=r")
12283         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12284   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12285    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12286    && (optimize_size
12287        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12288   "shr{l}\t{%2, %k0|%k0, %2}"
12289   [(set_attr "type" "ishift")
12290    (set_attr "mode" "SI")])
12292 (define_expand "lshrhi3"
12293   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12294         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12295                      (match_operand:QI 2 "nonmemory_operand" "")))
12296    (clobber (reg:CC FLAGS_REG))]
12297   "TARGET_HIMODE_MATH"
12298   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12300 (define_insn "*lshrhi3_1_one_bit"
12301   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12302         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12303                      (match_operand:QI 2 "const1_operand" "")))
12304    (clobber (reg:CC FLAGS_REG))]
12305   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12306    && (TARGET_SHIFT1 || optimize_size)"
12307   "shr{w}\t%0"
12308   [(set_attr "type" "ishift")
12309    (set (attr "length")
12310      (if_then_else (match_operand 0 "register_operand" "")
12311         (const_string "2")
12312         (const_string "*")))])
12314 (define_insn "*lshrhi3_1"
12315   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12316         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12317                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12318    (clobber (reg:CC FLAGS_REG))]
12319   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12320   "@
12321    shr{w}\t{%2, %0|%0, %2}
12322    shr{w}\t{%b2, %0|%0, %b2}"
12323   [(set_attr "type" "ishift")
12324    (set_attr "mode" "HI")])
12326 ;; This pattern can't accept a variable shift count, since shifts by
12327 ;; zero don't affect the flags.  We assume that shifts by constant
12328 ;; zero are optimized away.
12329 (define_insn "*lshrhi3_one_bit_cmp"
12330   [(set (reg FLAGS_REG)
12331         (compare
12332           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12333                        (match_operand:QI 2 "const1_operand" ""))
12334           (const_int 0)))
12335    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12336         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12337   "ix86_match_ccmode (insn, CCGOCmode)
12338    && (TARGET_SHIFT1 || optimize_size)
12339    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12340   "shr{w}\t%0"
12341   [(set_attr "type" "ishift")
12342    (set (attr "length")
12343      (if_then_else (match_operand:SI 0 "register_operand" "")
12344         (const_string "2")
12345         (const_string "*")))])
12347 (define_insn "*lshrhi3_one_bit_cconly"
12348   [(set (reg FLAGS_REG)
12349         (compare
12350           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12351                        (match_operand:QI 2 "const1_operand" ""))
12352           (const_int 0)))
12353    (clobber (match_scratch:HI 0 "=r"))]
12354   "ix86_match_ccmode (insn, CCGOCmode)
12355    && (TARGET_SHIFT1 || optimize_size)
12356    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12357   "shr{w}\t%0"
12358   [(set_attr "type" "ishift")
12359    (set_attr "length" "2")])
12361 ;; This pattern can't accept a variable shift count, since shifts by
12362 ;; zero don't affect the flags.  We assume that shifts by constant
12363 ;; zero are optimized away.
12364 (define_insn "*lshrhi3_cmp"
12365   [(set (reg FLAGS_REG)
12366         (compare
12367           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12369           (const_int 0)))
12370    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12371         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12372   "ix86_match_ccmode (insn, CCGOCmode)
12373    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12374    && (optimize_size
12375        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12376   "shr{w}\t{%2, %0|%0, %2}"
12377   [(set_attr "type" "ishift")
12378    (set_attr "mode" "HI")])
12380 (define_insn "*lshrhi3_cconly"
12381   [(set (reg FLAGS_REG)
12382         (compare
12383           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12384                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12385           (const_int 0)))
12386    (clobber (match_scratch:HI 0 "=r"))]
12387   "ix86_match_ccmode (insn, CCGOCmode)
12388    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12389    && (optimize_size
12390        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12391   "shr{w}\t{%2, %0|%0, %2}"
12392   [(set_attr "type" "ishift")
12393    (set_attr "mode" "HI")])
12395 (define_expand "lshrqi3"
12396   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12397         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12398                      (match_operand:QI 2 "nonmemory_operand" "")))
12399    (clobber (reg:CC FLAGS_REG))]
12400   "TARGET_QIMODE_MATH"
12401   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12403 (define_insn "*lshrqi3_1_one_bit"
12404   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12405         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12406                      (match_operand:QI 2 "const1_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12409    && (TARGET_SHIFT1 || optimize_size)"
12410   "shr{b}\t%0"
12411   [(set_attr "type" "ishift")
12412    (set (attr "length")
12413      (if_then_else (match_operand 0 "register_operand" "")
12414         (const_string "2")
12415         (const_string "*")))])
12417 (define_insn "*lshrqi3_1_one_bit_slp"
12418   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12419         (lshiftrt:QI (match_dup 0)
12420                      (match_operand:QI 1 "const1_operand" "")))
12421    (clobber (reg:CC FLAGS_REG))]
12422   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12423    && (TARGET_SHIFT1 || optimize_size)"
12424   "shr{b}\t%0"
12425   [(set_attr "type" "ishift1")
12426    (set (attr "length")
12427      (if_then_else (match_operand 0 "register_operand" "")
12428         (const_string "2")
12429         (const_string "*")))])
12431 (define_insn "*lshrqi3_1"
12432   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12433         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12434                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12435    (clobber (reg:CC FLAGS_REG))]
12436   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12437   "@
12438    shr{b}\t{%2, %0|%0, %2}
12439    shr{b}\t{%b2, %0|%0, %b2}"
12440   [(set_attr "type" "ishift")
12441    (set_attr "mode" "QI")])
12443 (define_insn "*lshrqi3_1_slp"
12444   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12445         (lshiftrt:QI (match_dup 0)
12446                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12447    (clobber (reg:CC FLAGS_REG))]
12448   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12449    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12450   "@
12451    shr{b}\t{%1, %0|%0, %1}
12452    shr{b}\t{%b1, %0|%0, %b1}"
12453   [(set_attr "type" "ishift1")
12454    (set_attr "mode" "QI")])
12456 ;; This pattern can't accept a variable shift count, since shifts by
12457 ;; zero don't affect the flags.  We assume that shifts by constant
12458 ;; zero are optimized away.
12459 (define_insn "*lshrqi2_one_bit_cmp"
12460   [(set (reg FLAGS_REG)
12461         (compare
12462           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12463                        (match_operand:QI 2 "const1_operand" ""))
12464           (const_int 0)))
12465    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12466         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12467   "ix86_match_ccmode (insn, CCGOCmode)
12468    && (TARGET_SHIFT1 || optimize_size)
12469    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12470   "shr{b}\t%0"
12471   [(set_attr "type" "ishift")
12472    (set (attr "length")
12473      (if_then_else (match_operand:SI 0 "register_operand" "")
12474         (const_string "2")
12475         (const_string "*")))])
12477 (define_insn "*lshrqi2_one_bit_cconly"
12478   [(set (reg FLAGS_REG)
12479         (compare
12480           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12481                        (match_operand:QI 2 "const1_operand" ""))
12482           (const_int 0)))
12483    (clobber (match_scratch:QI 0 "=q"))]
12484   "ix86_match_ccmode (insn, CCGOCmode)
12485    && (TARGET_SHIFT1 || optimize_size)
12486    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12487   "shr{b}\t%0"
12488   [(set_attr "type" "ishift")
12489    (set_attr "length" "2")])
12491 ;; This pattern can't accept a variable shift count, since shifts by
12492 ;; zero don't affect the flags.  We assume that shifts by constant
12493 ;; zero are optimized away.
12494 (define_insn "*lshrqi2_cmp"
12495   [(set (reg FLAGS_REG)
12496         (compare
12497           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12498                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12499           (const_int 0)))
12500    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12501         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12502   "ix86_match_ccmode (insn, CCGOCmode)
12503    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12504    && (optimize_size
12505        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12506   "shr{b}\t{%2, %0|%0, %2}"
12507   [(set_attr "type" "ishift")
12508    (set_attr "mode" "QI")])
12510 (define_insn "*lshrqi2_cconly"
12511   [(set (reg FLAGS_REG)
12512         (compare
12513           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12514                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12515           (const_int 0)))
12516    (clobber (match_scratch:QI 0 "=q"))]
12517   "ix86_match_ccmode (insn, CCGOCmode)
12518    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12519    && (optimize_size
12520        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12521   "shr{b}\t{%2, %0|%0, %2}"
12522   [(set_attr "type" "ishift")
12523    (set_attr "mode" "QI")])
12525 ;; Rotate instructions
12527 (define_expand "rotldi3"
12528   [(set (match_operand:DI 0 "shiftdi_operand" "")
12529         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12530                    (match_operand:QI 2 "nonmemory_operand" "")))
12531    (clobber (reg:CC FLAGS_REG))]
12532  ""
12534   if (TARGET_64BIT)
12535     {
12536       ix86_expand_binary_operator (ROTATE, DImode, operands);
12537       DONE;
12538     }
12539   if (!const_1_to_31_operand (operands[2], VOIDmode))
12540     FAIL;
12541   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12542   DONE;
12545 ;; Implement rotation using two double-precision shift instructions
12546 ;; and a scratch register.
12547 (define_insn_and_split "ix86_rotldi3"
12548  [(set (match_operand:DI 0 "register_operand" "=r")
12549        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12550                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12551   (clobber (reg:CC FLAGS_REG))
12552   (clobber (match_scratch:SI 3 "=&r"))]
12553  "!TARGET_64BIT"
12554  ""
12555  "&& reload_completed"
12556  [(set (match_dup 3) (match_dup 4))
12557   (parallel
12558    [(set (match_dup 4)
12559          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12560                  (lshiftrt:SI (match_dup 5)
12561                               (minus:QI (const_int 32) (match_dup 2)))))
12562     (clobber (reg:CC FLAGS_REG))])
12563   (parallel
12564    [(set (match_dup 5)
12565          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12566                  (lshiftrt:SI (match_dup 3)
12567                               (minus:QI (const_int 32) (match_dup 2)))))
12568     (clobber (reg:CC FLAGS_REG))])]
12569  "split_di (operands, 1, operands + 4, operands + 5);")
12571 (define_insn "*rotlsi3_1_one_bit_rex64"
12572   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12573         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12574                    (match_operand:QI 2 "const1_operand" "")))
12575    (clobber (reg:CC FLAGS_REG))]
12576   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12577    && (TARGET_SHIFT1 || optimize_size)"
12578   "rol{q}\t%0"
12579   [(set_attr "type" "rotate")
12580    (set (attr "length")
12581      (if_then_else (match_operand:DI 0 "register_operand" "")
12582         (const_string "2")
12583         (const_string "*")))])
12585 (define_insn "*rotldi3_1_rex64"
12586   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12587         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12588                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12589    (clobber (reg:CC FLAGS_REG))]
12590   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12591   "@
12592    rol{q}\t{%2, %0|%0, %2}
12593    rol{q}\t{%b2, %0|%0, %b2}"
12594   [(set_attr "type" "rotate")
12595    (set_attr "mode" "DI")])
12597 (define_expand "rotlsi3"
12598   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12599         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12600                    (match_operand:QI 2 "nonmemory_operand" "")))
12601    (clobber (reg:CC FLAGS_REG))]
12602   ""
12603   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12605 (define_insn "*rotlsi3_1_one_bit"
12606   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12607         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12608                    (match_operand:QI 2 "const1_operand" "")))
12609    (clobber (reg:CC FLAGS_REG))]
12610   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12611    && (TARGET_SHIFT1 || optimize_size)"
12612   "rol{l}\t%0"
12613   [(set_attr "type" "rotate")
12614    (set (attr "length")
12615      (if_then_else (match_operand:SI 0 "register_operand" "")
12616         (const_string "2")
12617         (const_string "*")))])
12619 (define_insn "*rotlsi3_1_one_bit_zext"
12620   [(set (match_operand:DI 0 "register_operand" "=r")
12621         (zero_extend:DI
12622           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12623                      (match_operand:QI 2 "const1_operand" ""))))
12624    (clobber (reg:CC FLAGS_REG))]
12625   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12626    && (TARGET_SHIFT1 || optimize_size)"
12627   "rol{l}\t%k0"
12628   [(set_attr "type" "rotate")
12629    (set_attr "length" "2")])
12631 (define_insn "*rotlsi3_1"
12632   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12633         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12634                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12635    (clobber (reg:CC FLAGS_REG))]
12636   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12637   "@
12638    rol{l}\t{%2, %0|%0, %2}
12639    rol{l}\t{%b2, %0|%0, %b2}"
12640   [(set_attr "type" "rotate")
12641    (set_attr "mode" "SI")])
12643 (define_insn "*rotlsi3_1_zext"
12644   [(set (match_operand:DI 0 "register_operand" "=r,r")
12645         (zero_extend:DI
12646           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12647                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12648    (clobber (reg:CC FLAGS_REG))]
12649   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12650   "@
12651    rol{l}\t{%2, %k0|%k0, %2}
12652    rol{l}\t{%b2, %k0|%k0, %b2}"
12653   [(set_attr "type" "rotate")
12654    (set_attr "mode" "SI")])
12656 (define_expand "rotlhi3"
12657   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12658         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12659                    (match_operand:QI 2 "nonmemory_operand" "")))
12660    (clobber (reg:CC FLAGS_REG))]
12661   "TARGET_HIMODE_MATH"
12662   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12664 (define_insn "*rotlhi3_1_one_bit"
12665   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12666         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12667                    (match_operand:QI 2 "const1_operand" "")))
12668    (clobber (reg:CC FLAGS_REG))]
12669   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12670    && (TARGET_SHIFT1 || optimize_size)"
12671   "rol{w}\t%0"
12672   [(set_attr "type" "rotate")
12673    (set (attr "length")
12674      (if_then_else (match_operand 0 "register_operand" "")
12675         (const_string "2")
12676         (const_string "*")))])
12678 (define_insn "*rotlhi3_1"
12679   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12680         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12681                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12682    (clobber (reg:CC FLAGS_REG))]
12683   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12684   "@
12685    rol{w}\t{%2, %0|%0, %2}
12686    rol{w}\t{%b2, %0|%0, %b2}"
12687   [(set_attr "type" "rotate")
12688    (set_attr "mode" "HI")])
12690 (define_expand "rotlqi3"
12691   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12692         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12693                    (match_operand:QI 2 "nonmemory_operand" "")))
12694    (clobber (reg:CC FLAGS_REG))]
12695   "TARGET_QIMODE_MATH"
12696   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12698 (define_insn "*rotlqi3_1_one_bit_slp"
12699   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12700         (rotate:QI (match_dup 0)
12701                    (match_operand:QI 1 "const1_operand" "")))
12702    (clobber (reg:CC FLAGS_REG))]
12703   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12704    && (TARGET_SHIFT1 || optimize_size)"
12705   "rol{b}\t%0"
12706   [(set_attr "type" "rotate1")
12707    (set (attr "length")
12708      (if_then_else (match_operand 0 "register_operand" "")
12709         (const_string "2")
12710         (const_string "*")))])
12712 (define_insn "*rotlqi3_1_one_bit"
12713   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12714         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12715                    (match_operand:QI 2 "const1_operand" "")))
12716    (clobber (reg:CC FLAGS_REG))]
12717   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12718    && (TARGET_SHIFT1 || optimize_size)"
12719   "rol{b}\t%0"
12720   [(set_attr "type" "rotate")
12721    (set (attr "length")
12722      (if_then_else (match_operand 0 "register_operand" "")
12723         (const_string "2")
12724         (const_string "*")))])
12726 (define_insn "*rotlqi3_1_slp"
12727   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12728         (rotate:QI (match_dup 0)
12729                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12730    (clobber (reg:CC FLAGS_REG))]
12731   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12732    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12733   "@
12734    rol{b}\t{%1, %0|%0, %1}
12735    rol{b}\t{%b1, %0|%0, %b1}"
12736   [(set_attr "type" "rotate1")
12737    (set_attr "mode" "QI")])
12739 (define_insn "*rotlqi3_1"
12740   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12741         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12742                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12743    (clobber (reg:CC FLAGS_REG))]
12744   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12745   "@
12746    rol{b}\t{%2, %0|%0, %2}
12747    rol{b}\t{%b2, %0|%0, %b2}"
12748   [(set_attr "type" "rotate")
12749    (set_attr "mode" "QI")])
12751 (define_expand "rotrdi3"
12752   [(set (match_operand:DI 0 "shiftdi_operand" "")
12753         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12754                    (match_operand:QI 2 "nonmemory_operand" "")))
12755    (clobber (reg:CC FLAGS_REG))]
12756  ""
12758   if (TARGET_64BIT)
12759     {
12760       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12761       DONE;
12762     }
12763   if (!const_1_to_31_operand (operands[2], VOIDmode))
12764     FAIL;
12765   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12766   DONE;
12769 ;; Implement rotation using two double-precision shift instructions
12770 ;; and a scratch register.
12771 (define_insn_and_split "ix86_rotrdi3"
12772  [(set (match_operand:DI 0 "register_operand" "=r")
12773        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12774                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12775   (clobber (reg:CC FLAGS_REG))
12776   (clobber (match_scratch:SI 3 "=&r"))]
12777  "!TARGET_64BIT"
12778  ""
12779  "&& reload_completed"
12780  [(set (match_dup 3) (match_dup 4))
12781   (parallel
12782    [(set (match_dup 4)
12783          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12784                  (ashift:SI (match_dup 5)
12785                             (minus:QI (const_int 32) (match_dup 2)))))
12786     (clobber (reg:CC FLAGS_REG))])
12787   (parallel
12788    [(set (match_dup 5)
12789          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12790                  (ashift:SI (match_dup 3)
12791                             (minus:QI (const_int 32) (match_dup 2)))))
12792     (clobber (reg:CC FLAGS_REG))])]
12793  "split_di (operands, 1, operands + 4, operands + 5);")
12795 (define_insn "*rotrdi3_1_one_bit_rex64"
12796   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12797         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12798                      (match_operand:QI 2 "const1_operand" "")))
12799    (clobber (reg:CC FLAGS_REG))]
12800   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12801    && (TARGET_SHIFT1 || optimize_size)"
12802   "ror{q}\t%0"
12803   [(set_attr "type" "rotate")
12804    (set (attr "length")
12805      (if_then_else (match_operand:DI 0 "register_operand" "")
12806         (const_string "2")
12807         (const_string "*")))])
12809 (define_insn "*rotrdi3_1_rex64"
12810   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12811         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12812                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12813    (clobber (reg:CC FLAGS_REG))]
12814   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12815   "@
12816    ror{q}\t{%2, %0|%0, %2}
12817    ror{q}\t{%b2, %0|%0, %b2}"
12818   [(set_attr "type" "rotate")
12819    (set_attr "mode" "DI")])
12821 (define_expand "rotrsi3"
12822   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12823         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12824                      (match_operand:QI 2 "nonmemory_operand" "")))
12825    (clobber (reg:CC FLAGS_REG))]
12826   ""
12827   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12829 (define_insn "*rotrsi3_1_one_bit"
12830   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12831         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12832                      (match_operand:QI 2 "const1_operand" "")))
12833    (clobber (reg:CC FLAGS_REG))]
12834   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12835    && (TARGET_SHIFT1 || optimize_size)"
12836   "ror{l}\t%0"
12837   [(set_attr "type" "rotate")
12838    (set (attr "length")
12839      (if_then_else (match_operand:SI 0 "register_operand" "")
12840         (const_string "2")
12841         (const_string "*")))])
12843 (define_insn "*rotrsi3_1_one_bit_zext"
12844   [(set (match_operand:DI 0 "register_operand" "=r")
12845         (zero_extend:DI
12846           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12847                        (match_operand:QI 2 "const1_operand" ""))))
12848    (clobber (reg:CC FLAGS_REG))]
12849   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12850    && (TARGET_SHIFT1 || optimize_size)"
12851   "ror{l}\t%k0"
12852   [(set_attr "type" "rotate")
12853    (set (attr "length")
12854      (if_then_else (match_operand:SI 0 "register_operand" "")
12855         (const_string "2")
12856         (const_string "*")))])
12858 (define_insn "*rotrsi3_1"
12859   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12860         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12861                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12862    (clobber (reg:CC FLAGS_REG))]
12863   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12864   "@
12865    ror{l}\t{%2, %0|%0, %2}
12866    ror{l}\t{%b2, %0|%0, %b2}"
12867   [(set_attr "type" "rotate")
12868    (set_attr "mode" "SI")])
12870 (define_insn "*rotrsi3_1_zext"
12871   [(set (match_operand:DI 0 "register_operand" "=r,r")
12872         (zero_extend:DI
12873           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12874                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12875    (clobber (reg:CC FLAGS_REG))]
12876   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12877   "@
12878    ror{l}\t{%2, %k0|%k0, %2}
12879    ror{l}\t{%b2, %k0|%k0, %b2}"
12880   [(set_attr "type" "rotate")
12881    (set_attr "mode" "SI")])
12883 (define_expand "rotrhi3"
12884   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12885         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12886                      (match_operand:QI 2 "nonmemory_operand" "")))
12887    (clobber (reg:CC FLAGS_REG))]
12888   "TARGET_HIMODE_MATH"
12889   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12891 (define_insn "*rotrhi3_one_bit"
12892   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12893         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12894                      (match_operand:QI 2 "const1_operand" "")))
12895    (clobber (reg:CC FLAGS_REG))]
12896   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12897    && (TARGET_SHIFT1 || optimize_size)"
12898   "ror{w}\t%0"
12899   [(set_attr "type" "rotate")
12900    (set (attr "length")
12901      (if_then_else (match_operand 0 "register_operand" "")
12902         (const_string "2")
12903         (const_string "*")))])
12905 (define_insn "*rotrhi3"
12906   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12907         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12908                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12909    (clobber (reg:CC FLAGS_REG))]
12910   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12911   "@
12912    ror{w}\t{%2, %0|%0, %2}
12913    ror{w}\t{%b2, %0|%0, %b2}"
12914   [(set_attr "type" "rotate")
12915    (set_attr "mode" "HI")])
12917 (define_expand "rotrqi3"
12918   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12919         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12920                      (match_operand:QI 2 "nonmemory_operand" "")))
12921    (clobber (reg:CC FLAGS_REG))]
12922   "TARGET_QIMODE_MATH"
12923   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12925 (define_insn "*rotrqi3_1_one_bit"
12926   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12927         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12928                      (match_operand:QI 2 "const1_operand" "")))
12929    (clobber (reg:CC FLAGS_REG))]
12930   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12931    && (TARGET_SHIFT1 || optimize_size)"
12932   "ror{b}\t%0"
12933   [(set_attr "type" "rotate")
12934    (set (attr "length")
12935      (if_then_else (match_operand 0 "register_operand" "")
12936         (const_string "2")
12937         (const_string "*")))])
12939 (define_insn "*rotrqi3_1_one_bit_slp"
12940   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12941         (rotatert:QI (match_dup 0)
12942                      (match_operand:QI 1 "const1_operand" "")))
12943    (clobber (reg:CC FLAGS_REG))]
12944   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12945    && (TARGET_SHIFT1 || optimize_size)"
12946   "ror{b}\t%0"
12947   [(set_attr "type" "rotate1")
12948    (set (attr "length")
12949      (if_then_else (match_operand 0 "register_operand" "")
12950         (const_string "2")
12951         (const_string "*")))])
12953 (define_insn "*rotrqi3_1"
12954   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12955         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12956                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12957    (clobber (reg:CC FLAGS_REG))]
12958   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12959   "@
12960    ror{b}\t{%2, %0|%0, %2}
12961    ror{b}\t{%b2, %0|%0, %b2}"
12962   [(set_attr "type" "rotate")
12963    (set_attr "mode" "QI")])
12965 (define_insn "*rotrqi3_1_slp"
12966   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12967         (rotatert:QI (match_dup 0)
12968                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12969    (clobber (reg:CC FLAGS_REG))]
12970   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12971    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12972   "@
12973    ror{b}\t{%1, %0|%0, %1}
12974    ror{b}\t{%b1, %0|%0, %b1}"
12975   [(set_attr "type" "rotate1")
12976    (set_attr "mode" "QI")])
12978 ;; Bit set / bit test instructions
12980 (define_expand "extv"
12981   [(set (match_operand:SI 0 "register_operand" "")
12982         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12983                          (match_operand:SI 2 "const8_operand" "")
12984                          (match_operand:SI 3 "const8_operand" "")))]
12985   ""
12987   /* Handle extractions from %ah et al.  */
12988   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12989     FAIL;
12991   /* From mips.md: extract_bit_field doesn't verify that our source
12992      matches the predicate, so check it again here.  */
12993   if (! ext_register_operand (operands[1], VOIDmode))
12994     FAIL;
12997 (define_expand "extzv"
12998   [(set (match_operand:SI 0 "register_operand" "")
12999         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13000                          (match_operand:SI 2 "const8_operand" "")
13001                          (match_operand:SI 3 "const8_operand" "")))]
13002   ""
13004   /* Handle extractions from %ah et al.  */
13005   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13006     FAIL;
13008   /* From mips.md: extract_bit_field doesn't verify that our source
13009      matches the predicate, so check it again here.  */
13010   if (! ext_register_operand (operands[1], VOIDmode))
13011     FAIL;
13014 (define_expand "insv"
13015   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13016                       (match_operand 1 "const8_operand" "")
13017                       (match_operand 2 "const8_operand" ""))
13018         (match_operand 3 "register_operand" ""))]
13019   ""
13021   /* Handle insertions to %ah et al.  */
13022   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13023     FAIL;
13025   /* From mips.md: insert_bit_field doesn't verify that our source
13026      matches the predicate, so check it again here.  */
13027   if (! ext_register_operand (operands[0], VOIDmode))
13028     FAIL;
13030   if (TARGET_64BIT)
13031     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13032   else
13033     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13035   DONE;
13038 ;; %%% bts, btr, btc, bt.
13039 ;; In general these instructions are *slow* when applied to memory,
13040 ;; since they enforce atomic operation.  When applied to registers,
13041 ;; it depends on the cpu implementation.  They're never faster than
13042 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13043 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13044 ;; within the instruction itself, so operating on bits in the high
13045 ;; 32-bits of a register becomes easier.
13047 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13048 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13049 ;; negdf respectively, so they can never be disabled entirely.
13051 (define_insn "*btsq"
13052   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13053                          (const_int 1)
13054                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13055         (const_int 1))
13056    (clobber (reg:CC FLAGS_REG))]
13057   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13058   "bts{q} %1,%0"
13059   [(set_attr "type" "alu1")])
13061 (define_insn "*btrq"
13062   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13063                          (const_int 1)
13064                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13065         (const_int 0))
13066    (clobber (reg:CC FLAGS_REG))]
13067   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13068   "btr{q} %1,%0"
13069   [(set_attr "type" "alu1")])
13071 (define_insn "*btcq"
13072   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13073                          (const_int 1)
13074                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13075         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13076    (clobber (reg:CC FLAGS_REG))]
13077   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13078   "btc{q} %1,%0"
13079   [(set_attr "type" "alu1")])
13081 ;; Allow Nocona to avoid these instructions if a register is available.
13083 (define_peephole2
13084   [(match_scratch:DI 2 "r")
13085    (parallel [(set (zero_extract:DI
13086                      (match_operand:DI 0 "register_operand" "")
13087                      (const_int 1)
13088                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13089                    (const_int 1))
13090               (clobber (reg:CC FLAGS_REG))])]
13091   "TARGET_64BIT && !TARGET_USE_BT"
13092   [(const_int 0)]
13094   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13095   rtx op1;
13097   if (HOST_BITS_PER_WIDE_INT >= 64)
13098     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13099   else if (i < HOST_BITS_PER_WIDE_INT)
13100     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13101   else
13102     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13104   op1 = immed_double_const (lo, hi, DImode);
13105   if (i >= 31)
13106     {
13107       emit_move_insn (operands[2], op1);
13108       op1 = operands[2];
13109     }
13111   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13112   DONE;
13115 (define_peephole2
13116   [(match_scratch:DI 2 "r")
13117    (parallel [(set (zero_extract:DI
13118                      (match_operand:DI 0 "register_operand" "")
13119                      (const_int 1)
13120                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13121                    (const_int 0))
13122               (clobber (reg:CC FLAGS_REG))])]
13123   "TARGET_64BIT && !TARGET_USE_BT"
13124   [(const_int 0)]
13126   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13127   rtx op1;
13129   if (HOST_BITS_PER_WIDE_INT >= 64)
13130     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13131   else if (i < HOST_BITS_PER_WIDE_INT)
13132     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13133   else
13134     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13136   op1 = immed_double_const (~lo, ~hi, DImode);
13137   if (i >= 32)
13138     {
13139       emit_move_insn (operands[2], op1);
13140       op1 = operands[2];
13141     }
13143   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13144   DONE;
13147 (define_peephole2
13148   [(match_scratch:DI 2 "r")
13149    (parallel [(set (zero_extract:DI
13150                      (match_operand:DI 0 "register_operand" "")
13151                      (const_int 1)
13152                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13153               (not:DI (zero_extract:DI
13154                         (match_dup 0) (const_int 1) (match_dup 1))))
13155               (clobber (reg:CC FLAGS_REG))])]
13156   "TARGET_64BIT && !TARGET_USE_BT"
13157   [(const_int 0)]
13159   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13160   rtx op1;
13162   if (HOST_BITS_PER_WIDE_INT >= 64)
13163     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13164   else if (i < HOST_BITS_PER_WIDE_INT)
13165     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13166   else
13167     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13169   op1 = immed_double_const (lo, hi, DImode);
13170   if (i >= 31)
13171     {
13172       emit_move_insn (operands[2], op1);
13173       op1 = operands[2];
13174     }
13176   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13177   DONE;
13180 ;; Store-flag instructions.
13182 ;; For all sCOND expanders, also expand the compare or test insn that
13183 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13185 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13186 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13187 ;; way, which can later delete the movzx if only QImode is needed.
13189 (define_expand "seq"
13190   [(set (match_operand:QI 0 "register_operand" "")
13191         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13192   ""
13193   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13195 (define_expand "sne"
13196   [(set (match_operand:QI 0 "register_operand" "")
13197         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13198   ""
13199   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13201 (define_expand "sgt"
13202   [(set (match_operand:QI 0 "register_operand" "")
13203         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13204   ""
13205   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13207 (define_expand "sgtu"
13208   [(set (match_operand:QI 0 "register_operand" "")
13209         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210   ""
13211   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13213 (define_expand "slt"
13214   [(set (match_operand:QI 0 "register_operand" "")
13215         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13216   ""
13217   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13219 (define_expand "sltu"
13220   [(set (match_operand:QI 0 "register_operand" "")
13221         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13222   ""
13223   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13225 (define_expand "sge"
13226   [(set (match_operand:QI 0 "register_operand" "")
13227         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228   ""
13229   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13231 (define_expand "sgeu"
13232   [(set (match_operand:QI 0 "register_operand" "")
13233         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234   ""
13235   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13237 (define_expand "sle"
13238   [(set (match_operand:QI 0 "register_operand" "")
13239         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240   ""
13241   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13243 (define_expand "sleu"
13244   [(set (match_operand:QI 0 "register_operand" "")
13245         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246   ""
13247   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13249 (define_expand "sunordered"
13250   [(set (match_operand:QI 0 "register_operand" "")
13251         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252   "TARGET_80387 || TARGET_SSE"
13253   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13255 (define_expand "sordered"
13256   [(set (match_operand:QI 0 "register_operand" "")
13257         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258   "TARGET_80387"
13259   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13261 (define_expand "suneq"
13262   [(set (match_operand:QI 0 "register_operand" "")
13263         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264   "TARGET_80387 || TARGET_SSE"
13265   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13267 (define_expand "sunge"
13268   [(set (match_operand:QI 0 "register_operand" "")
13269         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270   "TARGET_80387 || TARGET_SSE"
13271   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13273 (define_expand "sungt"
13274   [(set (match_operand:QI 0 "register_operand" "")
13275         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276   "TARGET_80387 || TARGET_SSE"
13277   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13279 (define_expand "sunle"
13280   [(set (match_operand:QI 0 "register_operand" "")
13281         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282   "TARGET_80387 || TARGET_SSE"
13283   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13285 (define_expand "sunlt"
13286   [(set (match_operand:QI 0 "register_operand" "")
13287         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13288   "TARGET_80387 || TARGET_SSE"
13289   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13291 (define_expand "sltgt"
13292   [(set (match_operand:QI 0 "register_operand" "")
13293         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294   "TARGET_80387 || TARGET_SSE"
13295   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13297 (define_insn "*setcc_1"
13298   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13299         (match_operator:QI 1 "ix86_comparison_operator"
13300           [(reg FLAGS_REG) (const_int 0)]))]
13301   ""
13302   "set%C1\t%0"
13303   [(set_attr "type" "setcc")
13304    (set_attr "mode" "QI")])
13306 (define_insn "*setcc_2"
13307   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13308         (match_operator:QI 1 "ix86_comparison_operator"
13309           [(reg FLAGS_REG) (const_int 0)]))]
13310   ""
13311   "set%C1\t%0"
13312   [(set_attr "type" "setcc")
13313    (set_attr "mode" "QI")])
13315 ;; In general it is not safe to assume too much about CCmode registers,
13316 ;; so simplify-rtx stops when it sees a second one.  Under certain
13317 ;; conditions this is safe on x86, so help combine not create
13319 ;;      seta    %al
13320 ;;      testb   %al, %al
13321 ;;      sete    %al
13323 (define_split
13324   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13325         (ne: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   PUT_MODE (operands[1], QImode);
13334 (define_split
13335   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13336         (ne:QI (match_operator 1 "ix86_comparison_operator"
13337                  [(reg FLAGS_REG) (const_int 0)])
13338             (const_int 0)))]
13339   ""
13340   [(set (match_dup 0) (match_dup 1))]
13342   PUT_MODE (operands[1], QImode);
13345 (define_split
13346   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13347         (eq:QI (match_operator 1 "ix86_comparison_operator"
13348                  [(reg FLAGS_REG) (const_int 0)])
13349             (const_int 0)))]
13350   ""
13351   [(set (match_dup 0) (match_dup 1))]
13353   rtx new_op1 = copy_rtx (operands[1]);
13354   operands[1] = new_op1;
13355   PUT_MODE (new_op1, QImode);
13356   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13357                                              GET_MODE (XEXP (new_op1, 0))));
13359   /* Make sure that (a) the CCmode we have for the flags is strong
13360      enough for the reversed compare or (b) we have a valid FP compare.  */
13361   if (! ix86_comparison_operator (new_op1, VOIDmode))
13362     FAIL;
13365 (define_split
13366   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13367         (eq:QI (match_operator 1 "ix86_comparison_operator"
13368                  [(reg FLAGS_REG) (const_int 0)])
13369             (const_int 0)))]
13370   ""
13371   [(set (match_dup 0) (match_dup 1))]
13373   rtx new_op1 = copy_rtx (operands[1]);
13374   operands[1] = new_op1;
13375   PUT_MODE (new_op1, QImode);
13376   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13377                                              GET_MODE (XEXP (new_op1, 0))));
13379   /* Make sure that (a) the CCmode we have for the flags is strong
13380      enough for the reversed compare or (b) we have a valid FP compare.  */
13381   if (! ix86_comparison_operator (new_op1, VOIDmode))
13382     FAIL;
13385 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13386 ;; subsequent logical operations are used to imitate conditional moves.
13387 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13388 ;; it directly.
13390 (define_insn "*sse_setccsf"
13391   [(set (match_operand:SF 0 "register_operand" "=x")
13392         (match_operator:SF 1 "sse_comparison_operator"
13393           [(match_operand:SF 2 "register_operand" "0")
13394            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13395   "TARGET_SSE"
13396   "cmp%D1ss\t{%3, %0|%0, %3}"
13397   [(set_attr "type" "ssecmp")
13398    (set_attr "mode" "SF")])
13400 (define_insn "*sse_setccdf"
13401   [(set (match_operand:DF 0 "register_operand" "=Y")
13402         (match_operator:DF 1 "sse_comparison_operator"
13403           [(match_operand:DF 2 "register_operand" "0")
13404            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13405   "TARGET_SSE2"
13406   "cmp%D1sd\t{%3, %0|%0, %3}"
13407   [(set_attr "type" "ssecmp")
13408    (set_attr "mode" "DF")])
13410 ;; Basic conditional jump instructions.
13411 ;; We ignore the overflow flag for signed branch instructions.
13413 ;; For all bCOND expanders, also expand the compare or test insn that
13414 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13416 (define_expand "beq"
13417   [(set (pc)
13418         (if_then_else (match_dup 1)
13419                       (label_ref (match_operand 0 "" ""))
13420                       (pc)))]
13421   ""
13422   "ix86_expand_branch (EQ, operands[0]); DONE;")
13424 (define_expand "bne"
13425   [(set (pc)
13426         (if_then_else (match_dup 1)
13427                       (label_ref (match_operand 0 "" ""))
13428                       (pc)))]
13429   ""
13430   "ix86_expand_branch (NE, operands[0]); DONE;")
13432 (define_expand "bgt"
13433   [(set (pc)
13434         (if_then_else (match_dup 1)
13435                       (label_ref (match_operand 0 "" ""))
13436                       (pc)))]
13437   ""
13438   "ix86_expand_branch (GT, operands[0]); DONE;")
13440 (define_expand "bgtu"
13441   [(set (pc)
13442         (if_then_else (match_dup 1)
13443                       (label_ref (match_operand 0 "" ""))
13444                       (pc)))]
13445   ""
13446   "ix86_expand_branch (GTU, operands[0]); DONE;")
13448 (define_expand "blt"
13449   [(set (pc)
13450         (if_then_else (match_dup 1)
13451                       (label_ref (match_operand 0 "" ""))
13452                       (pc)))]
13453   ""
13454   "ix86_expand_branch (LT, operands[0]); DONE;")
13456 (define_expand "bltu"
13457   [(set (pc)
13458         (if_then_else (match_dup 1)
13459                       (label_ref (match_operand 0 "" ""))
13460                       (pc)))]
13461   ""
13462   "ix86_expand_branch (LTU, operands[0]); DONE;")
13464 (define_expand "bge"
13465   [(set (pc)
13466         (if_then_else (match_dup 1)
13467                       (label_ref (match_operand 0 "" ""))
13468                       (pc)))]
13469   ""
13470   "ix86_expand_branch (GE, operands[0]); DONE;")
13472 (define_expand "bgeu"
13473   [(set (pc)
13474         (if_then_else (match_dup 1)
13475                       (label_ref (match_operand 0 "" ""))
13476                       (pc)))]
13477   ""
13478   "ix86_expand_branch (GEU, operands[0]); DONE;")
13480 (define_expand "ble"
13481   [(set (pc)
13482         (if_then_else (match_dup 1)
13483                       (label_ref (match_operand 0 "" ""))
13484                       (pc)))]
13485   ""
13486   "ix86_expand_branch (LE, operands[0]); DONE;")
13488 (define_expand "bleu"
13489   [(set (pc)
13490         (if_then_else (match_dup 1)
13491                       (label_ref (match_operand 0 "" ""))
13492                       (pc)))]
13493   ""
13494   "ix86_expand_branch (LEU, operands[0]); DONE;")
13496 (define_expand "bunordered"
13497   [(set (pc)
13498         (if_then_else (match_dup 1)
13499                       (label_ref (match_operand 0 "" ""))
13500                       (pc)))]
13501   "TARGET_80387 || TARGET_SSE_MATH"
13502   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13504 (define_expand "bordered"
13505   [(set (pc)
13506         (if_then_else (match_dup 1)
13507                       (label_ref (match_operand 0 "" ""))
13508                       (pc)))]
13509   "TARGET_80387 || TARGET_SSE_MATH"
13510   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13512 (define_expand "buneq"
13513   [(set (pc)
13514         (if_then_else (match_dup 1)
13515                       (label_ref (match_operand 0 "" ""))
13516                       (pc)))]
13517   "TARGET_80387 || TARGET_SSE_MATH"
13518   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13520 (define_expand "bunge"
13521   [(set (pc)
13522         (if_then_else (match_dup 1)
13523                       (label_ref (match_operand 0 "" ""))
13524                       (pc)))]
13525   "TARGET_80387 || TARGET_SSE_MATH"
13526   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13528 (define_expand "bungt"
13529   [(set (pc)
13530         (if_then_else (match_dup 1)
13531                       (label_ref (match_operand 0 "" ""))
13532                       (pc)))]
13533   "TARGET_80387 || TARGET_SSE_MATH"
13534   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13536 (define_expand "bunle"
13537   [(set (pc)
13538         (if_then_else (match_dup 1)
13539                       (label_ref (match_operand 0 "" ""))
13540                       (pc)))]
13541   "TARGET_80387 || TARGET_SSE_MATH"
13542   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13544 (define_expand "bunlt"
13545   [(set (pc)
13546         (if_then_else (match_dup 1)
13547                       (label_ref (match_operand 0 "" ""))
13548                       (pc)))]
13549   "TARGET_80387 || TARGET_SSE_MATH"
13550   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13552 (define_expand "bltgt"
13553   [(set (pc)
13554         (if_then_else (match_dup 1)
13555                       (label_ref (match_operand 0 "" ""))
13556                       (pc)))]
13557   "TARGET_80387 || TARGET_SSE_MATH"
13558   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13560 (define_insn "*jcc_1"
13561   [(set (pc)
13562         (if_then_else (match_operator 1 "ix86_comparison_operator"
13563                                       [(reg FLAGS_REG) (const_int 0)])
13564                       (label_ref (match_operand 0 "" ""))
13565                       (pc)))]
13566   ""
13567   "%+j%C1\t%l0"
13568   [(set_attr "type" "ibr")
13569    (set_attr "modrm" "0")
13570    (set (attr "length")
13571            (if_then_else (and (ge (minus (match_dup 0) (pc))
13572                                   (const_int -126))
13573                               (lt (minus (match_dup 0) (pc))
13574                                   (const_int 128)))
13575              (const_int 2)
13576              (const_int 6)))])
13578 (define_insn "*jcc_2"
13579   [(set (pc)
13580         (if_then_else (match_operator 1 "ix86_comparison_operator"
13581                                       [(reg FLAGS_REG) (const_int 0)])
13582                       (pc)
13583                       (label_ref (match_operand 0 "" ""))))]
13584   ""
13585   "%+j%c1\t%l0"
13586   [(set_attr "type" "ibr")
13587    (set_attr "modrm" "0")
13588    (set (attr "length")
13589            (if_then_else (and (ge (minus (match_dup 0) (pc))
13590                                   (const_int -126))
13591                               (lt (minus (match_dup 0) (pc))
13592                                   (const_int 128)))
13593              (const_int 2)
13594              (const_int 6)))])
13596 ;; In general it is not safe to assume too much about CCmode registers,
13597 ;; so simplify-rtx stops when it sees a second one.  Under certain
13598 ;; conditions this is safe on x86, so help combine not create
13600 ;;      seta    %al
13601 ;;      testb   %al, %al
13602 ;;      je      Lfoo
13604 (define_split
13605   [(set (pc)
13606         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13607                                       [(reg FLAGS_REG) (const_int 0)])
13608                           (const_int 0))
13609                       (label_ref (match_operand 1 "" ""))
13610                       (pc)))]
13611   ""
13612   [(set (pc)
13613         (if_then_else (match_dup 0)
13614                       (label_ref (match_dup 1))
13615                       (pc)))]
13617   PUT_MODE (operands[0], VOIDmode);
13620 (define_split
13621   [(set (pc)
13622         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13623                                       [(reg FLAGS_REG) (const_int 0)])
13624                           (const_int 0))
13625                       (label_ref (match_operand 1 "" ""))
13626                       (pc)))]
13627   ""
13628   [(set (pc)
13629         (if_then_else (match_dup 0)
13630                       (label_ref (match_dup 1))
13631                       (pc)))]
13633   rtx new_op0 = copy_rtx (operands[0]);
13634   operands[0] = new_op0;
13635   PUT_MODE (new_op0, VOIDmode);
13636   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13637                                              GET_MODE (XEXP (new_op0, 0))));
13639   /* Make sure that (a) the CCmode we have for the flags is strong
13640      enough for the reversed compare or (b) we have a valid FP compare.  */
13641   if (! ix86_comparison_operator (new_op0, VOIDmode))
13642     FAIL;
13645 ;; Define combination compare-and-branch fp compare instructions to use
13646 ;; during early optimization.  Splitting the operation apart early makes
13647 ;; for bad code when we want to reverse the operation.
13649 (define_insn "*fp_jcc_1_mixed"
13650   [(set (pc)
13651         (if_then_else (match_operator 0 "comparison_operator"
13652                         [(match_operand 1 "register_operand" "f,x")
13653                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13654           (label_ref (match_operand 3 "" ""))
13655           (pc)))
13656    (clobber (reg:CCFP FPSR_REG))
13657    (clobber (reg:CCFP FLAGS_REG))]
13658   "TARGET_MIX_SSE_I387
13659    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13660    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13661    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13662   "#")
13664 (define_insn "*fp_jcc_1_sse"
13665   [(set (pc)
13666         (if_then_else (match_operator 0 "comparison_operator"
13667                         [(match_operand 1 "register_operand" "x")
13668                          (match_operand 2 "nonimmediate_operand" "xm")])
13669           (label_ref (match_operand 3 "" ""))
13670           (pc)))
13671    (clobber (reg:CCFP FPSR_REG))
13672    (clobber (reg:CCFP FLAGS_REG))]
13673   "TARGET_SSE_MATH
13674    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13675    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13676    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13677   "#")
13679 (define_insn "*fp_jcc_1_387"
13680   [(set (pc)
13681         (if_then_else (match_operator 0 "comparison_operator"
13682                         [(match_operand 1 "register_operand" "f")
13683                          (match_operand 2 "register_operand" "f")])
13684           (label_ref (match_operand 3 "" ""))
13685           (pc)))
13686    (clobber (reg:CCFP FPSR_REG))
13687    (clobber (reg:CCFP FLAGS_REG))]
13688   "TARGET_CMOVE && TARGET_80387
13689    && FLOAT_MODE_P (GET_MODE (operands[1]))
13690    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13691    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13692   "#")
13694 (define_insn "*fp_jcc_2_mixed"
13695   [(set (pc)
13696         (if_then_else (match_operator 0 "comparison_operator"
13697                         [(match_operand 1 "register_operand" "f,x")
13698                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13699           (pc)
13700           (label_ref (match_operand 3 "" ""))))
13701    (clobber (reg:CCFP FPSR_REG))
13702    (clobber (reg:CCFP FLAGS_REG))]
13703   "TARGET_MIX_SSE_I387
13704    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13705    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13706    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13707   "#")
13709 (define_insn "*fp_jcc_2_sse"
13710   [(set (pc)
13711         (if_then_else (match_operator 0 "comparison_operator"
13712                         [(match_operand 1 "register_operand" "x")
13713                          (match_operand 2 "nonimmediate_operand" "xm")])
13714           (pc)
13715           (label_ref (match_operand 3 "" ""))))
13716    (clobber (reg:CCFP FPSR_REG))
13717    (clobber (reg:CCFP FLAGS_REG))]
13718   "TARGET_SSE_MATH
13719    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13720    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13721    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13722   "#")
13724 (define_insn "*fp_jcc_2_387"
13725   [(set (pc)
13726         (if_then_else (match_operator 0 "comparison_operator"
13727                         [(match_operand 1 "register_operand" "f")
13728                          (match_operand 2 "register_operand" "f")])
13729           (pc)
13730           (label_ref (match_operand 3 "" ""))))
13731    (clobber (reg:CCFP FPSR_REG))
13732    (clobber (reg:CCFP FLAGS_REG))]
13733   "TARGET_CMOVE && TARGET_80387
13734    && FLOAT_MODE_P (GET_MODE (operands[1]))
13735    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13736    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13737   "#")
13739 (define_insn "*fp_jcc_3_387"
13740   [(set (pc)
13741         (if_then_else (match_operator 0 "comparison_operator"
13742                         [(match_operand 1 "register_operand" "f")
13743                          (match_operand 2 "nonimmediate_operand" "fm")])
13744           (label_ref (match_operand 3 "" ""))
13745           (pc)))
13746    (clobber (reg:CCFP FPSR_REG))
13747    (clobber (reg:CCFP FLAGS_REG))
13748    (clobber (match_scratch:HI 4 "=a"))]
13749   "TARGET_80387
13750    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13751    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13752    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13753    && SELECT_CC_MODE (GET_CODE (operands[0]),
13754                       operands[1], operands[2]) == CCFPmode
13755    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13756   "#")
13758 (define_insn "*fp_jcc_4_387"
13759   [(set (pc)
13760         (if_then_else (match_operator 0 "comparison_operator"
13761                         [(match_operand 1 "register_operand" "f")
13762                          (match_operand 2 "nonimmediate_operand" "fm")])
13763           (pc)
13764           (label_ref (match_operand 3 "" ""))))
13765    (clobber (reg:CCFP FPSR_REG))
13766    (clobber (reg:CCFP FLAGS_REG))
13767    (clobber (match_scratch:HI 4 "=a"))]
13768   "TARGET_80387
13769    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13770    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13772    && SELECT_CC_MODE (GET_CODE (operands[0]),
13773                       operands[1], operands[2]) == CCFPmode
13774    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13775   "#")
13777 (define_insn "*fp_jcc_5_387"
13778   [(set (pc)
13779         (if_then_else (match_operator 0 "comparison_operator"
13780                         [(match_operand 1 "register_operand" "f")
13781                          (match_operand 2 "register_operand" "f")])
13782           (label_ref (match_operand 3 "" ""))
13783           (pc)))
13784    (clobber (reg:CCFP FPSR_REG))
13785    (clobber (reg:CCFP FLAGS_REG))
13786    (clobber (match_scratch:HI 4 "=a"))]
13787   "TARGET_80387
13788    && FLOAT_MODE_P (GET_MODE (operands[1]))
13789    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13790    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13791   "#")
13793 (define_insn "*fp_jcc_6_387"
13794   [(set (pc)
13795         (if_then_else (match_operator 0 "comparison_operator"
13796                         [(match_operand 1 "register_operand" "f")
13797                          (match_operand 2 "register_operand" "f")])
13798           (pc)
13799           (label_ref (match_operand 3 "" ""))))
13800    (clobber (reg:CCFP FPSR_REG))
13801    (clobber (reg:CCFP FLAGS_REG))
13802    (clobber (match_scratch:HI 4 "=a"))]
13803   "TARGET_80387
13804    && FLOAT_MODE_P (GET_MODE (operands[1]))
13805    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13806    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13807   "#")
13809 (define_insn "*fp_jcc_7_387"
13810   [(set (pc)
13811         (if_then_else (match_operator 0 "comparison_operator"
13812                         [(match_operand 1 "register_operand" "f")
13813                          (match_operand 2 "const0_operand" "X")])
13814           (label_ref (match_operand 3 "" ""))
13815           (pc)))
13816    (clobber (reg:CCFP FPSR_REG))
13817    (clobber (reg:CCFP FLAGS_REG))
13818    (clobber (match_scratch:HI 4 "=a"))]
13819   "TARGET_80387
13820    && FLOAT_MODE_P (GET_MODE (operands[1]))
13821    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13822    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13823    && SELECT_CC_MODE (GET_CODE (operands[0]),
13824                       operands[1], operands[2]) == CCFPmode
13825    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13826   "#")
13828 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13829 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13830 ;; with a precedence over other operators and is always put in the first
13831 ;; place. Swap condition and operands to match ficom instruction.
13833 (define_insn "*fp_jcc_8<mode>_387"
13834   [(set (pc)
13835         (if_then_else (match_operator 0 "comparison_operator"
13836                         [(match_operator 1 "float_operator"
13837                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13838                            (match_operand 3 "register_operand" "f,f")])
13839           (label_ref (match_operand 4 "" ""))
13840           (pc)))
13841    (clobber (reg:CCFP FPSR_REG))
13842    (clobber (reg:CCFP FLAGS_REG))
13843    (clobber (match_scratch:HI 5 "=a,a"))]
13844   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13845    && FLOAT_MODE_P (GET_MODE (operands[3]))
13846    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13847    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13848    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13849    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13850   "#")
13852 (define_split
13853   [(set (pc)
13854         (if_then_else (match_operator 0 "comparison_operator"
13855                         [(match_operand 1 "register_operand" "")
13856                          (match_operand 2 "nonimmediate_operand" "")])
13857           (match_operand 3 "" "")
13858           (match_operand 4 "" "")))
13859    (clobber (reg:CCFP FPSR_REG))
13860    (clobber (reg:CCFP FLAGS_REG))]
13861   "reload_completed"
13862   [(const_int 0)]
13864   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13865                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13866   DONE;
13869 (define_split
13870   [(set (pc)
13871         (if_then_else (match_operator 0 "comparison_operator"
13872                         [(match_operand 1 "register_operand" "")
13873                          (match_operand 2 "general_operand" "")])
13874           (match_operand 3 "" "")
13875           (match_operand 4 "" "")))
13876    (clobber (reg:CCFP FPSR_REG))
13877    (clobber (reg:CCFP FLAGS_REG))
13878    (clobber (match_scratch:HI 5 "=a"))]
13879   "reload_completed"
13880   [(const_int 0)]
13882   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13883                         operands[3], operands[4], operands[5], NULL_RTX);
13884   DONE;
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 "memory_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] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13902   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13903                         operands[3], operands[7],
13904                         operands[4], operands[5], operands[6], NULL_RTX);
13905   DONE;
13908 ;; %%% Kill this when reload knows how to do it.
13909 (define_split
13910   [(set (pc)
13911         (if_then_else (match_operator 0 "comparison_operator"
13912                         [(match_operator 1 "float_operator"
13913                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13914                            (match_operand 3 "register_operand" "")])
13915           (match_operand 4 "" "")
13916           (match_operand 5 "" "")))
13917    (clobber (reg:CCFP FPSR_REG))
13918    (clobber (reg:CCFP FLAGS_REG))
13919    (clobber (match_scratch:HI 6 "=a"))]
13920   "reload_completed"
13921   [(const_int 0)]
13923   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13924   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13925   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13926                         operands[3], operands[7],
13927                         operands[4], operands[5], operands[6], operands[2]);
13928   DONE;
13931 ;; Unconditional and other jump instructions
13933 (define_insn "jump"
13934   [(set (pc)
13935         (label_ref (match_operand 0 "" "")))]
13936   ""
13937   "jmp\t%l0"
13938   [(set_attr "type" "ibr")
13939    (set (attr "length")
13940            (if_then_else (and (ge (minus (match_dup 0) (pc))
13941                                   (const_int -126))
13942                               (lt (minus (match_dup 0) (pc))
13943                                   (const_int 128)))
13944              (const_int 2)
13945              (const_int 5)))
13946    (set_attr "modrm" "0")])
13948 (define_expand "indirect_jump"
13949   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13950   ""
13951   "")
13953 (define_insn "*indirect_jump"
13954   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13955   "!TARGET_64BIT"
13956   "jmp\t%A0"
13957   [(set_attr "type" "ibr")
13958    (set_attr "length_immediate" "0")])
13960 (define_insn "*indirect_jump_rtx64"
13961   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13962   "TARGET_64BIT"
13963   "jmp\t%A0"
13964   [(set_attr "type" "ibr")
13965    (set_attr "length_immediate" "0")])
13967 (define_expand "tablejump"
13968   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13969               (use (label_ref (match_operand 1 "" "")))])]
13970   ""
13972   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13973      relative.  Convert the relative address to an absolute address.  */
13974   if (flag_pic)
13975     {
13976       rtx op0, op1;
13977       enum rtx_code code;
13979       if (TARGET_64BIT)
13980         {
13981           code = PLUS;
13982           op0 = operands[0];
13983           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13984         }
13985       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13986         {
13987           code = PLUS;
13988           op0 = operands[0];
13989           op1 = pic_offset_table_rtx;
13990         }
13991       else
13992         {
13993           code = MINUS;
13994           op0 = pic_offset_table_rtx;
13995           op1 = operands[0];
13996         }
13998       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13999                                          OPTAB_DIRECT);
14000     }
14003 (define_insn "*tablejump_1"
14004   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14005    (use (label_ref (match_operand 1 "" "")))]
14006   "!TARGET_64BIT"
14007   "jmp\t%A0"
14008   [(set_attr "type" "ibr")
14009    (set_attr "length_immediate" "0")])
14011 (define_insn "*tablejump_1_rtx64"
14012   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14013    (use (label_ref (match_operand 1 "" "")))]
14014   "TARGET_64BIT"
14015   "jmp\t%A0"
14016   [(set_attr "type" "ibr")
14017    (set_attr "length_immediate" "0")])
14019 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14021 (define_peephole2
14022   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14023    (set (match_operand:QI 1 "register_operand" "")
14024         (match_operator:QI 2 "ix86_comparison_operator"
14025           [(reg FLAGS_REG) (const_int 0)]))
14026    (set (match_operand 3 "q_regs_operand" "")
14027         (zero_extend (match_dup 1)))]
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 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14042 (define_peephole2
14043   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14044    (set (match_operand:QI 1 "register_operand" "")
14045         (match_operator:QI 2 "ix86_comparison_operator"
14046           [(reg FLAGS_REG) (const_int 0)]))
14047    (parallel [(set (match_operand 3 "q_regs_operand" "")
14048                    (zero_extend (match_dup 1)))
14049               (clobber (reg:CC FLAGS_REG))])]
14050   "(peep2_reg_dead_p (3, operands[1])
14051     || operands_match_p (operands[1], operands[3]))
14052    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14053   [(set (match_dup 4) (match_dup 0))
14054    (set (strict_low_part (match_dup 5))
14055         (match_dup 2))]
14057   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14058   operands[5] = gen_lowpart (QImode, operands[3]);
14059   ix86_expand_clear (operands[3]);
14062 ;; Call instructions.
14064 ;; The predicates normally associated with named expanders are not properly
14065 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14066 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14068 ;; Call subroutine returning no value.
14070 (define_expand "call_pop"
14071   [(parallel [(call (match_operand:QI 0 "" "")
14072                     (match_operand:SI 1 "" ""))
14073               (set (reg:SI SP_REG)
14074                    (plus:SI (reg:SI SP_REG)
14075                             (match_operand:SI 3 "" "")))])]
14076   "!TARGET_64BIT"
14078   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14079   DONE;
14082 (define_insn "*call_pop_0"
14083   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14084          (match_operand:SI 1 "" ""))
14085    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14086                             (match_operand:SI 2 "immediate_operand" "")))]
14087   "!TARGET_64BIT"
14089   if (SIBLING_CALL_P (insn))
14090     return "jmp\t%P0";
14091   else
14092     return "call\t%P0";
14094   [(set_attr "type" "call")])
14096 (define_insn "*call_pop_1"
14097   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14098          (match_operand:SI 1 "" ""))
14099    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14100                             (match_operand:SI 2 "immediate_operand" "i")))]
14101   "!TARGET_64BIT"
14103   if (constant_call_address_operand (operands[0], Pmode))
14104     {
14105       if (SIBLING_CALL_P (insn))
14106         return "jmp\t%P0";
14107       else
14108         return "call\t%P0";
14109     }
14110   if (SIBLING_CALL_P (insn))
14111     return "jmp\t%A0";
14112   else
14113     return "call\t%A0";
14115   [(set_attr "type" "call")])
14117 (define_expand "call"
14118   [(call (match_operand:QI 0 "" "")
14119          (match_operand 1 "" ""))
14120    (use (match_operand 2 "" ""))]
14121   ""
14123   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14124   DONE;
14127 (define_expand "sibcall"
14128   [(call (match_operand:QI 0 "" "")
14129          (match_operand 1 "" ""))
14130    (use (match_operand 2 "" ""))]
14131   ""
14133   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14134   DONE;
14137 (define_insn "*call_0"
14138   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14139          (match_operand 1 "" ""))]
14140   ""
14142   if (SIBLING_CALL_P (insn))
14143     return "jmp\t%P0";
14144   else
14145     return "call\t%P0";
14147   [(set_attr "type" "call")])
14149 (define_insn "*call_1"
14150   [(call (mem:QI (match_operand:SI 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"
14161   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14162          (match_operand 1 "" ""))]
14163   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14165   if (constant_call_address_operand (operands[0], Pmode))
14166     return "jmp\t%P0";
14167   return "jmp\t%A0";
14169   [(set_attr "type" "call")])
14171 (define_insn "*call_1_rex64"
14172   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14173          (match_operand 1 "" ""))]
14174   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14176   if (constant_call_address_operand (operands[0], Pmode))
14177     return "call\t%P0";
14178   return "call\t%A0";
14180   [(set_attr "type" "call")])
14182 (define_insn "*sibcall_1_rex64"
14183   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14184          (match_operand 1 "" ""))]
14185   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14186   "jmp\t%P0"
14187   [(set_attr "type" "call")])
14189 (define_insn "*sibcall_1_rex64_v"
14190   [(call (mem:QI (reg:DI R11_REG))
14191          (match_operand 0 "" ""))]
14192   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14193   "jmp\t*%%r11"
14194   [(set_attr "type" "call")])
14197 ;; Call subroutine, returning value in operand 0
14199 (define_expand "call_value_pop"
14200   [(parallel [(set (match_operand 0 "" "")
14201                    (call (match_operand:QI 1 "" "")
14202                          (match_operand:SI 2 "" "")))
14203               (set (reg:SI SP_REG)
14204                    (plus:SI (reg:SI SP_REG)
14205                             (match_operand:SI 4 "" "")))])]
14206   "!TARGET_64BIT"
14208   ix86_expand_call (operands[0], operands[1], operands[2],
14209                     operands[3], operands[4], 0);
14210   DONE;
14213 (define_expand "call_value"
14214   [(set (match_operand 0 "" "")
14215         (call (match_operand:QI 1 "" "")
14216               (match_operand:SI 2 "" "")))
14217    (use (match_operand:SI 3 "" ""))]
14218   ;; Operand 2 not used on the i386.
14219   ""
14221   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14222   DONE;
14225 (define_expand "sibcall_value"
14226   [(set (match_operand 0 "" "")
14227         (call (match_operand:QI 1 "" "")
14228               (match_operand:SI 2 "" "")))
14229    (use (match_operand:SI 3 "" ""))]
14230   ;; Operand 2 not used on the i386.
14231   ""
14233   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14234   DONE;
14237 ;; Call subroutine returning any type.
14239 (define_expand "untyped_call"
14240   [(parallel [(call (match_operand 0 "" "")
14241                     (const_int 0))
14242               (match_operand 1 "" "")
14243               (match_operand 2 "" "")])]
14244   ""
14246   int i;
14248   /* In order to give reg-stack an easier job in validating two
14249      coprocessor registers as containing a possible return value,
14250      simply pretend the untyped call returns a complex long double
14251      value.  */
14253   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14254                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14255                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14256                     NULL, 0);
14258   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14259     {
14260       rtx set = XVECEXP (operands[2], 0, i);
14261       emit_move_insn (SET_DEST (set), SET_SRC (set));
14262     }
14264   /* The optimizer does not know that the call sets the function value
14265      registers we stored in the result block.  We avoid problems by
14266      claiming that all hard registers are used and clobbered at this
14267      point.  */
14268   emit_insn (gen_blockage (const0_rtx));
14270   DONE;
14273 ;; Prologue and epilogue instructions
14275 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14276 ;; all of memory.  This blocks insns from being moved across this point.
14278 (define_insn "blockage"
14279   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14280   ""
14281   ""
14282   [(set_attr "length" "0")])
14284 ;; Insn emitted into the body of a function to return from a function.
14285 ;; This is only done if the function's epilogue is known to be simple.
14286 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14288 (define_expand "return"
14289   [(return)]
14290   "ix86_can_use_return_insn_p ()"
14292   if (current_function_pops_args)
14293     {
14294       rtx popc = GEN_INT (current_function_pops_args);
14295       emit_jump_insn (gen_return_pop_internal (popc));
14296       DONE;
14297     }
14300 (define_insn "return_internal"
14301   [(return)]
14302   "reload_completed"
14303   "ret"
14304   [(set_attr "length" "1")
14305    (set_attr "length_immediate" "0")
14306    (set_attr "modrm" "0")])
14308 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14309 ;; instruction Athlon and K8 have.
14311 (define_insn "return_internal_long"
14312   [(return)
14313    (unspec [(const_int 0)] UNSPEC_REP)]
14314   "reload_completed"
14315   "rep {;} ret"
14316   [(set_attr "length" "1")
14317    (set_attr "length_immediate" "0")
14318    (set_attr "prefix_rep" "1")
14319    (set_attr "modrm" "0")])
14321 (define_insn "return_pop_internal"
14322   [(return)
14323    (use (match_operand:SI 0 "const_int_operand" ""))]
14324   "reload_completed"
14325   "ret\t%0"
14326   [(set_attr "length" "3")
14327    (set_attr "length_immediate" "2")
14328    (set_attr "modrm" "0")])
14330 (define_insn "return_indirect_internal"
14331   [(return)
14332    (use (match_operand:SI 0 "register_operand" "r"))]
14333   "reload_completed"
14334   "jmp\t%A0"
14335   [(set_attr "type" "ibr")
14336    (set_attr "length_immediate" "0")])
14338 (define_insn "nop"
14339   [(const_int 0)]
14340   ""
14341   "nop"
14342   [(set_attr "length" "1")
14343    (set_attr "length_immediate" "0")
14344    (set_attr "modrm" "0")])
14346 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14347 ;; branch prediction penalty for the third jump in a 16-byte
14348 ;; block on K8.
14350 (define_insn "align"
14351   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14352   ""
14354 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14355   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14356 #else
14357   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14358      The align insn is used to avoid 3 jump instructions in the row to improve
14359      branch prediction and the benefits hardly outweigh the cost of extra 8
14360      nops on the average inserted by full alignment pseudo operation.  */
14361 #endif
14362   return "";
14364   [(set_attr "length" "16")])
14366 (define_expand "prologue"
14367   [(const_int 1)]
14368   ""
14369   "ix86_expand_prologue (); DONE;")
14371 (define_insn "set_got"
14372   [(set (match_operand:SI 0 "register_operand" "=r")
14373         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14374    (clobber (reg:CC FLAGS_REG))]
14375   "!TARGET_64BIT"
14376   { return output_set_got (operands[0], NULL_RTX); }
14377   [(set_attr "type" "multi")
14378    (set_attr "length" "12")])
14380 (define_insn "set_got_labelled"
14381   [(set (match_operand:SI 0 "register_operand" "=r")
14382         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14383          UNSPEC_SET_GOT))
14384    (clobber (reg:CC FLAGS_REG))]
14385   "!TARGET_64BIT"
14386   { return output_set_got (operands[0], operands[1]); }
14387   [(set_attr "type" "multi")
14388    (set_attr "length" "12")])
14390 (define_insn "set_got_rex64"
14391   [(set (match_operand:DI 0 "register_operand" "=r")
14392         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14393   "TARGET_64BIT"
14394   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14395   [(set_attr "type" "lea")
14396    (set_attr "length" "6")])
14398 (define_expand "epilogue"
14399   [(const_int 1)]
14400   ""
14401   "ix86_expand_epilogue (1); DONE;")
14403 (define_expand "sibcall_epilogue"
14404   [(const_int 1)]
14405   ""
14406   "ix86_expand_epilogue (0); DONE;")
14408 (define_expand "eh_return"
14409   [(use (match_operand 0 "register_operand" ""))]
14410   ""
14412   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14414   /* Tricky bit: we write the address of the handler to which we will
14415      be returning into someone else's stack frame, one word below the
14416      stack address we wish to restore.  */
14417   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14418   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14419   tmp = gen_rtx_MEM (Pmode, tmp);
14420   emit_move_insn (tmp, ra);
14422   if (Pmode == SImode)
14423     emit_jump_insn (gen_eh_return_si (sa));
14424   else
14425     emit_jump_insn (gen_eh_return_di (sa));
14426   emit_barrier ();
14427   DONE;
14430 (define_insn_and_split "eh_return_si"
14431   [(set (pc)
14432         (unspec [(match_operand:SI 0 "register_operand" "c")]
14433                  UNSPEC_EH_RETURN))]
14434   "!TARGET_64BIT"
14435   "#"
14436   "reload_completed"
14437   [(const_int 1)]
14438   "ix86_expand_epilogue (2); DONE;")
14440 (define_insn_and_split "eh_return_di"
14441   [(set (pc)
14442         (unspec [(match_operand:DI 0 "register_operand" "c")]
14443                  UNSPEC_EH_RETURN))]
14444   "TARGET_64BIT"
14445   "#"
14446   "reload_completed"
14447   [(const_int 1)]
14448   "ix86_expand_epilogue (2); DONE;")
14450 (define_insn "leave"
14451   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14452    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14453    (clobber (mem:BLK (scratch)))]
14454   "!TARGET_64BIT"
14455   "leave"
14456   [(set_attr "type" "leave")])
14458 (define_insn "leave_rex64"
14459   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14460    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14461    (clobber (mem:BLK (scratch)))]
14462   "TARGET_64BIT"
14463   "leave"
14464   [(set_attr "type" "leave")])
14466 (define_expand "ffssi2"
14467   [(parallel
14468      [(set (match_operand:SI 0 "register_operand" "")
14469            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14470       (clobber (match_scratch:SI 2 ""))
14471       (clobber (reg:CC FLAGS_REG))])]
14472   ""
14473   "")
14475 (define_insn_and_split "*ffs_cmove"
14476   [(set (match_operand:SI 0 "register_operand" "=r")
14477         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14478    (clobber (match_scratch:SI 2 "=&r"))
14479    (clobber (reg:CC FLAGS_REG))]
14480   "TARGET_CMOVE"
14481   "#"
14482   "&& reload_completed"
14483   [(set (match_dup 2) (const_int -1))
14484    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14485               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14486    (set (match_dup 0) (if_then_else:SI
14487                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14488                         (match_dup 2)
14489                         (match_dup 0)))
14490    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14491               (clobber (reg:CC FLAGS_REG))])]
14492   "")
14494 (define_insn_and_split "*ffs_no_cmove"
14495   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14496         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14497    (clobber (match_scratch:SI 2 "=&q"))
14498    (clobber (reg:CC FLAGS_REG))]
14499   ""
14500   "#"
14501   "reload_completed"
14502   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14503               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14504    (set (strict_low_part (match_dup 3))
14505         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14506    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14507               (clobber (reg:CC FLAGS_REG))])
14508    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14509               (clobber (reg:CC FLAGS_REG))])
14510    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14511               (clobber (reg:CC FLAGS_REG))])]
14513   operands[3] = gen_lowpart (QImode, operands[2]);
14514   ix86_expand_clear (operands[2]);
14517 (define_insn "*ffssi_1"
14518   [(set (reg:CCZ FLAGS_REG)
14519         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14520                      (const_int 0)))
14521    (set (match_operand:SI 0 "register_operand" "=r")
14522         (ctz:SI (match_dup 1)))]
14523   ""
14524   "bsf{l}\t{%1, %0|%0, %1}"
14525   [(set_attr "prefix_0f" "1")])
14527 (define_expand "ffsdi2"
14528   [(parallel
14529      [(set (match_operand:DI 0 "register_operand" "")
14530            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14531       (clobber (match_scratch:DI 2 ""))
14532       (clobber (reg:CC FLAGS_REG))])]
14533   "TARGET_64BIT && TARGET_CMOVE"
14534   "")
14536 (define_insn_and_split "*ffs_rex64"
14537   [(set (match_operand:DI 0 "register_operand" "=r")
14538         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14539    (clobber (match_scratch:DI 2 "=&r"))
14540    (clobber (reg:CC FLAGS_REG))]
14541   "TARGET_64BIT && TARGET_CMOVE"
14542   "#"
14543   "&& reload_completed"
14544   [(set (match_dup 2) (const_int -1))
14545    (parallel [(set (reg:CCZ FLAGS_REG)
14546                    (compare:CCZ (match_dup 1) (const_int 0)))
14547               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14548    (set (match_dup 0) (if_then_else:DI
14549                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14550                         (match_dup 2)
14551                         (match_dup 0)))
14552    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14553               (clobber (reg:CC FLAGS_REG))])]
14554   "")
14556 (define_insn "*ffsdi_1"
14557   [(set (reg:CCZ FLAGS_REG)
14558         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14559                      (const_int 0)))
14560    (set (match_operand:DI 0 "register_operand" "=r")
14561         (ctz:DI (match_dup 1)))]
14562   "TARGET_64BIT"
14563   "bsf{q}\t{%1, %0|%0, %1}"
14564   [(set_attr "prefix_0f" "1")])
14566 (define_insn "ctzsi2"
14567   [(set (match_operand:SI 0 "register_operand" "=r")
14568         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14569    (clobber (reg:CC FLAGS_REG))]
14570   ""
14571   "bsf{l}\t{%1, %0|%0, %1}"
14572   [(set_attr "prefix_0f" "1")])
14574 (define_insn "ctzdi2"
14575   [(set (match_operand:DI 0 "register_operand" "=r")
14576         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14577    (clobber (reg:CC FLAGS_REG))]
14578   "TARGET_64BIT"
14579   "bsf{q}\t{%1, %0|%0, %1}"
14580   [(set_attr "prefix_0f" "1")])
14582 (define_expand "clzsi2"
14583   [(parallel
14584      [(set (match_operand:SI 0 "register_operand" "")
14585            (minus:SI (const_int 31)
14586                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14587       (clobber (reg:CC FLAGS_REG))])
14588    (parallel
14589      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14590       (clobber (reg:CC FLAGS_REG))])]
14591   ""
14592   "")
14594 (define_insn "*bsr"
14595   [(set (match_operand:SI 0 "register_operand" "=r")
14596         (minus:SI (const_int 31)
14597                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14598    (clobber (reg:CC FLAGS_REG))]
14599   ""
14600   "bsr{l}\t{%1, %0|%0, %1}"
14601   [(set_attr "prefix_0f" "1")])
14603 (define_insn "bswapsi2"
14604   [(set (match_operand:SI 0 "register_operand" "=r")
14605         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14606    (clobber (reg:CC FLAGS_REG))]
14607   "TARGET_BSWAP"
14608   "bswap\t%k0"
14609   [(set_attr "prefix_0f" "1")
14610    (set_attr "length" "2")])
14612 (define_insn "bswapdi2"
14613   [(set (match_operand:DI 0 "register_operand" "=r")
14614         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14615    (clobber (reg:CC FLAGS_REG))]
14616   "TARGET_64BIT && TARGET_BSWAP"
14617   "bswap\t%0"
14618   [(set_attr "prefix_0f" "1")
14619    (set_attr "length" "3")])
14621 (define_expand "clzdi2"
14622   [(parallel
14623      [(set (match_operand:DI 0 "register_operand" "")
14624            (minus:DI (const_int 63)
14625                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14626       (clobber (reg:CC FLAGS_REG))])
14627    (parallel
14628      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14629       (clobber (reg:CC FLAGS_REG))])]
14630   "TARGET_64BIT"
14631   "")
14633 (define_insn "*bsr_rex64"
14634   [(set (match_operand:DI 0 "register_operand" "=r")
14635         (minus:DI (const_int 63)
14636                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14637    (clobber (reg:CC FLAGS_REG))]
14638   "TARGET_64BIT"
14639   "bsr{q}\t{%1, %0|%0, %1}"
14640   [(set_attr "prefix_0f" "1")])
14642 ;; Thread-local storage patterns for ELF.
14644 ;; Note that these code sequences must appear exactly as shown
14645 ;; in order to allow linker relaxation.
14647 (define_insn "*tls_global_dynamic_32_gnu"
14648   [(set (match_operand:SI 0 "register_operand" "=a")
14649         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14650                     (match_operand:SI 2 "tls_symbolic_operand" "")
14651                     (match_operand:SI 3 "call_insn_operand" "")]
14652                     UNSPEC_TLS_GD))
14653    (clobber (match_scratch:SI 4 "=d"))
14654    (clobber (match_scratch:SI 5 "=c"))
14655    (clobber (reg:CC FLAGS_REG))]
14656   "!TARGET_64BIT && TARGET_GNU_TLS"
14657   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14658   [(set_attr "type" "multi")
14659    (set_attr "length" "12")])
14661 (define_insn "*tls_global_dynamic_32_sun"
14662   [(set (match_operand:SI 0 "register_operand" "=a")
14663         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14664                     (match_operand:SI 2 "tls_symbolic_operand" "")
14665                     (match_operand:SI 3 "call_insn_operand" "")]
14666                     UNSPEC_TLS_GD))
14667    (clobber (match_scratch:SI 4 "=d"))
14668    (clobber (match_scratch:SI 5 "=c"))
14669    (clobber (reg:CC FLAGS_REG))]
14670   "!TARGET_64BIT && TARGET_SUN_TLS"
14671   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14672         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14673   [(set_attr "type" "multi")
14674    (set_attr "length" "14")])
14676 (define_expand "tls_global_dynamic_32"
14677   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14678                    (unspec:SI
14679                     [(match_dup 2)
14680                      (match_operand:SI 1 "tls_symbolic_operand" "")
14681                      (match_dup 3)]
14682                     UNSPEC_TLS_GD))
14683               (clobber (match_scratch:SI 4 ""))
14684               (clobber (match_scratch:SI 5 ""))
14685               (clobber (reg:CC FLAGS_REG))])]
14686   ""
14688   if (flag_pic)
14689     operands[2] = pic_offset_table_rtx;
14690   else
14691     {
14692       operands[2] = gen_reg_rtx (Pmode);
14693       emit_insn (gen_set_got (operands[2]));
14694     }
14695   if (TARGET_GNU2_TLS)
14696     {
14697        emit_insn (gen_tls_dynamic_gnu2_32
14698                   (operands[0], operands[1], operands[2]));
14699        DONE;
14700     }
14701   operands[3] = ix86_tls_get_addr ();
14704 (define_insn "*tls_global_dynamic_64"
14705   [(set (match_operand:DI 0 "register_operand" "=a")
14706         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14707                  (match_operand:DI 3 "" "")))
14708    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14709               UNSPEC_TLS_GD)]
14710   "TARGET_64BIT"
14711   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14712   [(set_attr "type" "multi")
14713    (set_attr "length" "16")])
14715 (define_expand "tls_global_dynamic_64"
14716   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14717                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14718               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14719                          UNSPEC_TLS_GD)])]
14720   ""
14722   if (TARGET_GNU2_TLS)
14723     {
14724        emit_insn (gen_tls_dynamic_gnu2_64
14725                   (operands[0], operands[1]));
14726        DONE;
14727     }
14728   operands[2] = ix86_tls_get_addr ();
14731 (define_insn "*tls_local_dynamic_base_32_gnu"
14732   [(set (match_operand:SI 0 "register_operand" "=a")
14733         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14734                     (match_operand:SI 2 "call_insn_operand" "")]
14735                    UNSPEC_TLS_LD_BASE))
14736    (clobber (match_scratch:SI 3 "=d"))
14737    (clobber (match_scratch:SI 4 "=c"))
14738    (clobber (reg:CC FLAGS_REG))]
14739   "!TARGET_64BIT && TARGET_GNU_TLS"
14740   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14741   [(set_attr "type" "multi")
14742    (set_attr "length" "11")])
14744 (define_insn "*tls_local_dynamic_base_32_sun"
14745   [(set (match_operand:SI 0 "register_operand" "=a")
14746         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14747                     (match_operand:SI 2 "call_insn_operand" "")]
14748                    UNSPEC_TLS_LD_BASE))
14749    (clobber (match_scratch:SI 3 "=d"))
14750    (clobber (match_scratch:SI 4 "=c"))
14751    (clobber (reg:CC FLAGS_REG))]
14752   "!TARGET_64BIT && TARGET_SUN_TLS"
14753   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14754         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14755   [(set_attr "type" "multi")
14756    (set_attr "length" "13")])
14758 (define_expand "tls_local_dynamic_base_32"
14759   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14760                    (unspec:SI [(match_dup 1) (match_dup 2)]
14761                               UNSPEC_TLS_LD_BASE))
14762               (clobber (match_scratch:SI 3 ""))
14763               (clobber (match_scratch:SI 4 ""))
14764               (clobber (reg:CC FLAGS_REG))])]
14765   ""
14767   if (flag_pic)
14768     operands[1] = pic_offset_table_rtx;
14769   else
14770     {
14771       operands[1] = gen_reg_rtx (Pmode);
14772       emit_insn (gen_set_got (operands[1]));
14773     }
14774   if (TARGET_GNU2_TLS)
14775     {
14776        emit_insn (gen_tls_dynamic_gnu2_32
14777                   (operands[0], ix86_tls_module_base (), operands[1]));
14778        DONE;
14779     }
14780   operands[2] = ix86_tls_get_addr ();
14783 (define_insn "*tls_local_dynamic_base_64"
14784   [(set (match_operand:DI 0 "register_operand" "=a")
14785         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14786                  (match_operand:DI 2 "" "")))
14787    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14788   "TARGET_64BIT"
14789   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14790   [(set_attr "type" "multi")
14791    (set_attr "length" "12")])
14793 (define_expand "tls_local_dynamic_base_64"
14794   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14795                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14796               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14797   ""
14799   if (TARGET_GNU2_TLS)
14800     {
14801        emit_insn (gen_tls_dynamic_gnu2_64
14802                   (operands[0], ix86_tls_module_base ()));
14803        DONE;
14804     }
14805   operands[1] = ix86_tls_get_addr ();
14808 ;; Local dynamic of a single variable is a lose.  Show combine how
14809 ;; to convert that back to global dynamic.
14811 (define_insn_and_split "*tls_local_dynamic_32_once"
14812   [(set (match_operand:SI 0 "register_operand" "=a")
14813         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14814                              (match_operand:SI 2 "call_insn_operand" "")]
14815                             UNSPEC_TLS_LD_BASE)
14816                  (const:SI (unspec:SI
14817                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14818                             UNSPEC_DTPOFF))))
14819    (clobber (match_scratch:SI 4 "=d"))
14820    (clobber (match_scratch:SI 5 "=c"))
14821    (clobber (reg:CC FLAGS_REG))]
14822   ""
14823   "#"
14824   ""
14825   [(parallel [(set (match_dup 0)
14826                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14827                               UNSPEC_TLS_GD))
14828               (clobber (match_dup 4))
14829               (clobber (match_dup 5))
14830               (clobber (reg:CC FLAGS_REG))])]
14831   "")
14833 ;; Load and add the thread base pointer from %gs:0.
14835 (define_insn "*load_tp_si"
14836   [(set (match_operand:SI 0 "register_operand" "=r")
14837         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14838   "!TARGET_64BIT"
14839   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14840   [(set_attr "type" "imov")
14841    (set_attr "modrm" "0")
14842    (set_attr "length" "7")
14843    (set_attr "memory" "load")
14844    (set_attr "imm_disp" "false")])
14846 (define_insn "*add_tp_si"
14847   [(set (match_operand:SI 0 "register_operand" "=r")
14848         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14849                  (match_operand:SI 1 "register_operand" "0")))
14850    (clobber (reg:CC FLAGS_REG))]
14851   "!TARGET_64BIT"
14852   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14853   [(set_attr "type" "alu")
14854    (set_attr "modrm" "0")
14855    (set_attr "length" "7")
14856    (set_attr "memory" "load")
14857    (set_attr "imm_disp" "false")])
14859 (define_insn "*load_tp_di"
14860   [(set (match_operand:DI 0 "register_operand" "=r")
14861         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14862   "TARGET_64BIT"
14863   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14864   [(set_attr "type" "imov")
14865    (set_attr "modrm" "0")
14866    (set_attr "length" "7")
14867    (set_attr "memory" "load")
14868    (set_attr "imm_disp" "false")])
14870 (define_insn "*add_tp_di"
14871   [(set (match_operand:DI 0 "register_operand" "=r")
14872         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14873                  (match_operand:DI 1 "register_operand" "0")))
14874    (clobber (reg:CC FLAGS_REG))]
14875   "TARGET_64BIT"
14876   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14877   [(set_attr "type" "alu")
14878    (set_attr "modrm" "0")
14879    (set_attr "length" "7")
14880    (set_attr "memory" "load")
14881    (set_attr "imm_disp" "false")])
14883 ;; GNU2 TLS patterns can be split.
14885 (define_expand "tls_dynamic_gnu2_32"
14886   [(set (match_dup 3)
14887         (plus:SI (match_operand:SI 2 "register_operand" "")
14888                  (const:SI
14889                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14890                              UNSPEC_TLSDESC))))
14891    (parallel
14892     [(set (match_operand:SI 0 "register_operand" "")
14893           (unspec:SI [(match_dup 1) (match_dup 3)
14894                       (match_dup 2) (reg:SI SP_REG)]
14895                       UNSPEC_TLSDESC))
14896      (clobber (reg:CC FLAGS_REG))])]
14897   "!TARGET_64BIT && TARGET_GNU2_TLS"
14899   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14900   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14903 (define_insn "*tls_dynamic_lea_32"
14904   [(set (match_operand:SI 0 "register_operand" "=r")
14905         (plus:SI (match_operand:SI 1 "register_operand" "b")
14906                  (const:SI
14907                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14908                               UNSPEC_TLSDESC))))]
14909   "!TARGET_64BIT && TARGET_GNU2_TLS"
14910   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14911   [(set_attr "type" "lea")
14912    (set_attr "mode" "SI")
14913    (set_attr "length" "6")
14914    (set_attr "length_address" "4")])
14916 (define_insn "*tls_dynamic_call_32"
14917   [(set (match_operand:SI 0 "register_operand" "=a")
14918         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14919                     (match_operand:SI 2 "register_operand" "0")
14920                     ;; we have to make sure %ebx still points to the GOT
14921                     (match_operand:SI 3 "register_operand" "b")
14922                     (reg:SI SP_REG)]
14923                    UNSPEC_TLSDESC))
14924    (clobber (reg:CC FLAGS_REG))]
14925   "!TARGET_64BIT && TARGET_GNU2_TLS"
14926   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14927   [(set_attr "type" "call")
14928    (set_attr "length" "2")
14929    (set_attr "length_address" "0")])
14931 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14932   [(set (match_operand:SI 0 "register_operand" "=&a")
14933         (plus:SI
14934          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14935                      (match_operand:SI 4 "" "")
14936                      (match_operand:SI 2 "register_operand" "b")
14937                      (reg:SI SP_REG)]
14938                     UNSPEC_TLSDESC)
14939          (const:SI (unspec:SI
14940                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14941                     UNSPEC_DTPOFF))))
14942    (clobber (reg:CC FLAGS_REG))]
14943   "!TARGET_64BIT && TARGET_GNU2_TLS"
14944   "#"
14945   ""
14946   [(set (match_dup 0) (match_dup 5))]
14948   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14949   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14952 (define_expand "tls_dynamic_gnu2_64"
14953   [(set (match_dup 2)
14954         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14955                    UNSPEC_TLSDESC))
14956    (parallel
14957     [(set (match_operand:DI 0 "register_operand" "")
14958           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14959                      UNSPEC_TLSDESC))
14960      (clobber (reg:CC FLAGS_REG))])]
14961   "TARGET_64BIT && TARGET_GNU2_TLS"
14963   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14964   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14967 (define_insn "*tls_dynamic_lea_64"
14968   [(set (match_operand:DI 0 "register_operand" "=r")
14969         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14970                    UNSPEC_TLSDESC))]
14971   "TARGET_64BIT && TARGET_GNU2_TLS"
14972   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14973   [(set_attr "type" "lea")
14974    (set_attr "mode" "DI")
14975    (set_attr "length" "7")
14976    (set_attr "length_address" "4")])
14978 (define_insn "*tls_dynamic_call_64"
14979   [(set (match_operand:DI 0 "register_operand" "=a")
14980         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14981                     (match_operand:DI 2 "register_operand" "0")
14982                     (reg:DI SP_REG)]
14983                    UNSPEC_TLSDESC))
14984    (clobber (reg:CC FLAGS_REG))]
14985   "TARGET_64BIT && TARGET_GNU2_TLS"
14986   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14987   [(set_attr "type" "call")
14988    (set_attr "length" "2")
14989    (set_attr "length_address" "0")])
14991 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14992   [(set (match_operand:DI 0 "register_operand" "=&a")
14993         (plus:DI
14994          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14995                      (match_operand:DI 3 "" "")
14996                      (reg:DI SP_REG)]
14997                     UNSPEC_TLSDESC)
14998          (const:DI (unspec:DI
14999                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15000                     UNSPEC_DTPOFF))))
15001    (clobber (reg:CC FLAGS_REG))]
15002   "TARGET_64BIT && TARGET_GNU2_TLS"
15003   "#"
15004   ""
15005   [(set (match_dup 0) (match_dup 4))]
15007   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15008   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15013 ;; These patterns match the binary 387 instructions for addM3, subM3,
15014 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15015 ;; SFmode.  The first is the normal insn, the second the same insn but
15016 ;; with one operand a conversion, and the third the same insn but with
15017 ;; the other operand a conversion.  The conversion may be SFmode or
15018 ;; SImode if the target mode DFmode, but only SImode if the target mode
15019 ;; is SFmode.
15021 ;; Gcc is slightly more smart about handling normal two address instructions
15022 ;; so use special patterns for add and mull.
15024 (define_insn "*fop_sf_comm_mixed"
15025   [(set (match_operand:SF 0 "register_operand" "=f,x")
15026         (match_operator:SF 3 "binary_fp_operator"
15027                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15028                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15029   "TARGET_MIX_SSE_I387
15030    && COMMUTATIVE_ARITH_P (operands[3])
15031    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15032   "* return output_387_binary_op (insn, operands);"
15033   [(set (attr "type")
15034         (if_then_else (eq_attr "alternative" "1")
15035            (if_then_else (match_operand:SF 3 "mult_operator" "")
15036               (const_string "ssemul")
15037               (const_string "sseadd"))
15038            (if_then_else (match_operand:SF 3 "mult_operator" "")
15039               (const_string "fmul")
15040               (const_string "fop"))))
15041    (set_attr "mode" "SF")])
15043 (define_insn "*fop_sf_comm_sse"
15044   [(set (match_operand:SF 0 "register_operand" "=x")
15045         (match_operator:SF 3 "binary_fp_operator"
15046                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15047                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15048   "TARGET_SSE_MATH
15049    && COMMUTATIVE_ARITH_P (operands[3])
15050    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15051   "* return output_387_binary_op (insn, operands);"
15052   [(set (attr "type")
15053         (if_then_else (match_operand:SF 3 "mult_operator" "")
15054            (const_string "ssemul")
15055            (const_string "sseadd")))
15056    (set_attr "mode" "SF")])
15058 (define_insn "*fop_sf_comm_i387"
15059   [(set (match_operand:SF 0 "register_operand" "=f")
15060         (match_operator:SF 3 "binary_fp_operator"
15061                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15062                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15063   "TARGET_80387
15064    && COMMUTATIVE_ARITH_P (operands[3])
15065    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15066   "* return output_387_binary_op (insn, operands);"
15067   [(set (attr "type")
15068         (if_then_else (match_operand:SF 3 "mult_operator" "")
15069            (const_string "fmul")
15070            (const_string "fop")))
15071    (set_attr "mode" "SF")])
15073 (define_insn "*fop_sf_1_mixed"
15074   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15075         (match_operator:SF 3 "binary_fp_operator"
15076                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15077                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15078   "TARGET_MIX_SSE_I387
15079    && !COMMUTATIVE_ARITH_P (operands[3])
15080    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15081   "* return output_387_binary_op (insn, operands);"
15082   [(set (attr "type")
15083         (cond [(and (eq_attr "alternative" "2")
15084                     (match_operand:SF 3 "mult_operator" ""))
15085                  (const_string "ssemul")
15086                (and (eq_attr "alternative" "2")
15087                     (match_operand:SF 3 "div_operator" ""))
15088                  (const_string "ssediv")
15089                (eq_attr "alternative" "2")
15090                  (const_string "sseadd")
15091                (match_operand:SF 3 "mult_operator" "")
15092                  (const_string "fmul")
15093                (match_operand:SF 3 "div_operator" "")
15094                  (const_string "fdiv")
15095               ]
15096               (const_string "fop")))
15097    (set_attr "mode" "SF")])
15099 (define_insn "*fop_sf_1_sse"
15100   [(set (match_operand:SF 0 "register_operand" "=x")
15101         (match_operator:SF 3 "binary_fp_operator"
15102                         [(match_operand:SF 1 "register_operand" "0")
15103                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15104   "TARGET_SSE_MATH
15105    && !COMMUTATIVE_ARITH_P (operands[3])"
15106   "* return output_387_binary_op (insn, operands);"
15107   [(set (attr "type")
15108         (cond [(match_operand:SF 3 "mult_operator" "")
15109                  (const_string "ssemul")
15110                (match_operand:SF 3 "div_operator" "")
15111                  (const_string "ssediv")
15112               ]
15113               (const_string "sseadd")))
15114    (set_attr "mode" "SF")])
15116 ;; This pattern is not fully shadowed by the pattern above.
15117 (define_insn "*fop_sf_1_i387"
15118   [(set (match_operand:SF 0 "register_operand" "=f,f")
15119         (match_operator:SF 3 "binary_fp_operator"
15120                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15121                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15122   "TARGET_80387 && !TARGET_SSE_MATH
15123    && !COMMUTATIVE_ARITH_P (operands[3])
15124    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15125   "* return output_387_binary_op (insn, operands);"
15126   [(set (attr "type")
15127         (cond [(match_operand:SF 3 "mult_operator" "")
15128                  (const_string "fmul")
15129                (match_operand:SF 3 "div_operator" "")
15130                  (const_string "fdiv")
15131               ]
15132               (const_string "fop")))
15133    (set_attr "mode" "SF")])
15135 ;; ??? Add SSE splitters for these!
15136 (define_insn "*fop_sf_2<mode>_i387"
15137   [(set (match_operand:SF 0 "register_operand" "=f,f")
15138         (match_operator:SF 3 "binary_fp_operator"
15139           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15140            (match_operand:SF 2 "register_operand" "0,0")]))]
15141   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15142   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15143   [(set (attr "type")
15144         (cond [(match_operand:SF 3 "mult_operator" "")
15145                  (const_string "fmul")
15146                (match_operand:SF 3 "div_operator" "")
15147                  (const_string "fdiv")
15148               ]
15149               (const_string "fop")))
15150    (set_attr "fp_int_src" "true")
15151    (set_attr "mode" "<MODE>")])
15153 (define_insn "*fop_sf_3<mode>_i387"
15154   [(set (match_operand:SF 0 "register_operand" "=f,f")
15155         (match_operator:SF 3 "binary_fp_operator"
15156           [(match_operand:SF 1 "register_operand" "0,0")
15157            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15158   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15159   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15160   [(set (attr "type")
15161         (cond [(match_operand:SF 3 "mult_operator" "")
15162                  (const_string "fmul")
15163                (match_operand:SF 3 "div_operator" "")
15164                  (const_string "fdiv")
15165               ]
15166               (const_string "fop")))
15167    (set_attr "fp_int_src" "true")
15168    (set_attr "mode" "<MODE>")])
15170 (define_insn "*fop_df_comm_mixed"
15171   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15172         (match_operator:DF 3 "binary_fp_operator"
15173                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15174                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15175   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15176    && COMMUTATIVE_ARITH_P (operands[3])
15177    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15178   "* return output_387_binary_op (insn, operands);"
15179   [(set (attr "type")
15180         (if_then_else (eq_attr "alternative" "1")
15181            (if_then_else (match_operand:DF 3 "mult_operator" "")
15182               (const_string "ssemul")
15183               (const_string "sseadd"))
15184            (if_then_else (match_operand:DF 3 "mult_operator" "")
15185               (const_string "fmul")
15186               (const_string "fop"))))
15187    (set_attr "mode" "DF")])
15189 (define_insn "*fop_df_comm_sse"
15190   [(set (match_operand:DF 0 "register_operand" "=Y")
15191         (match_operator:DF 3 "binary_fp_operator"
15192                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15193                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15194   "TARGET_SSE2 && TARGET_SSE_MATH
15195    && COMMUTATIVE_ARITH_P (operands[3])
15196    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15197   "* return output_387_binary_op (insn, operands);"
15198   [(set (attr "type")
15199         (if_then_else (match_operand:DF 3 "mult_operator" "")
15200            (const_string "ssemul")
15201            (const_string "sseadd")))
15202    (set_attr "mode" "DF")])
15204 (define_insn "*fop_df_comm_i387"
15205   [(set (match_operand:DF 0 "register_operand" "=f")
15206         (match_operator:DF 3 "binary_fp_operator"
15207                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15208                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15209   "TARGET_80387
15210    && COMMUTATIVE_ARITH_P (operands[3])
15211    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15212   "* return output_387_binary_op (insn, operands);"
15213   [(set (attr "type")
15214         (if_then_else (match_operand:DF 3 "mult_operator" "")
15215            (const_string "fmul")
15216            (const_string "fop")))
15217    (set_attr "mode" "DF")])
15219 (define_insn "*fop_df_1_mixed"
15220   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15221         (match_operator:DF 3 "binary_fp_operator"
15222                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15223                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15224   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15225    && !COMMUTATIVE_ARITH_P (operands[3])
15226    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15227   "* return output_387_binary_op (insn, operands);"
15228   [(set (attr "type")
15229         (cond [(and (eq_attr "alternative" "2")
15230                     (match_operand:DF 3 "mult_operator" ""))
15231                  (const_string "ssemul")
15232                (and (eq_attr "alternative" "2")
15233                     (match_operand:DF 3 "div_operator" ""))
15234                  (const_string "ssediv")
15235                (eq_attr "alternative" "2")
15236                  (const_string "sseadd")
15237                (match_operand:DF 3 "mult_operator" "")
15238                  (const_string "fmul")
15239                (match_operand:DF 3 "div_operator" "")
15240                  (const_string "fdiv")
15241               ]
15242               (const_string "fop")))
15243    (set_attr "mode" "DF")])
15245 (define_insn "*fop_df_1_sse"
15246   [(set (match_operand:DF 0 "register_operand" "=Y")
15247         (match_operator:DF 3 "binary_fp_operator"
15248                         [(match_operand:DF 1 "register_operand" "0")
15249                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15250   "TARGET_SSE2 && TARGET_SSE_MATH
15251    && !COMMUTATIVE_ARITH_P (operands[3])"
15252   "* return output_387_binary_op (insn, operands);"
15253   [(set_attr "mode" "DF")
15254    (set (attr "type")
15255         (cond [(match_operand:DF 3 "mult_operator" "")
15256                  (const_string "ssemul")
15257                (match_operand:DF 3 "div_operator" "")
15258                  (const_string "ssediv")
15259               ]
15260               (const_string "sseadd")))])
15262 ;; This pattern is not fully shadowed by the pattern above.
15263 (define_insn "*fop_df_1_i387"
15264   [(set (match_operand:DF 0 "register_operand" "=f,f")
15265         (match_operator:DF 3 "binary_fp_operator"
15266                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15267                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15268   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15269    && !COMMUTATIVE_ARITH_P (operands[3])
15270    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15271   "* return output_387_binary_op (insn, operands);"
15272   [(set (attr "type")
15273         (cond [(match_operand:DF 3 "mult_operator" "")
15274                  (const_string "fmul")
15275                (match_operand:DF 3 "div_operator" "")
15276                  (const_string "fdiv")
15277               ]
15278               (const_string "fop")))
15279    (set_attr "mode" "DF")])
15281 ;; ??? Add SSE splitters for these!
15282 (define_insn "*fop_df_2<mode>_i387"
15283   [(set (match_operand:DF 0 "register_operand" "=f,f")
15284         (match_operator:DF 3 "binary_fp_operator"
15285            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15286             (match_operand:DF 2 "register_operand" "0,0")]))]
15287   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15288    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15289   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15290   [(set (attr "type")
15291         (cond [(match_operand:DF 3 "mult_operator" "")
15292                  (const_string "fmul")
15293                (match_operand:DF 3 "div_operator" "")
15294                  (const_string "fdiv")
15295               ]
15296               (const_string "fop")))
15297    (set_attr "fp_int_src" "true")
15298    (set_attr "mode" "<MODE>")])
15300 (define_insn "*fop_df_3<mode>_i387"
15301   [(set (match_operand:DF 0 "register_operand" "=f,f")
15302         (match_operator:DF 3 "binary_fp_operator"
15303            [(match_operand:DF 1 "register_operand" "0,0")
15304             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15305   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15306    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15307   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15308   [(set (attr "type")
15309         (cond [(match_operand:DF 3 "mult_operator" "")
15310                  (const_string "fmul")
15311                (match_operand:DF 3 "div_operator" "")
15312                  (const_string "fdiv")
15313               ]
15314               (const_string "fop")))
15315    (set_attr "fp_int_src" "true")
15316    (set_attr "mode" "<MODE>")])
15318 (define_insn "*fop_df_4_i387"
15319   [(set (match_operand:DF 0 "register_operand" "=f,f")
15320         (match_operator:DF 3 "binary_fp_operator"
15321            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15322             (match_operand:DF 2 "register_operand" "0,f")]))]
15323   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15324    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15325   "* return output_387_binary_op (insn, operands);"
15326   [(set (attr "type")
15327         (cond [(match_operand:DF 3 "mult_operator" "")
15328                  (const_string "fmul")
15329                (match_operand:DF 3 "div_operator" "")
15330                  (const_string "fdiv")
15331               ]
15332               (const_string "fop")))
15333    (set_attr "mode" "SF")])
15335 (define_insn "*fop_df_5_i387"
15336   [(set (match_operand:DF 0 "register_operand" "=f,f")
15337         (match_operator:DF 3 "binary_fp_operator"
15338           [(match_operand:DF 1 "register_operand" "0,f")
15339            (float_extend:DF
15340             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15341   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15342   "* return output_387_binary_op (insn, operands);"
15343   [(set (attr "type")
15344         (cond [(match_operand:DF 3 "mult_operator" "")
15345                  (const_string "fmul")
15346                (match_operand:DF 3 "div_operator" "")
15347                  (const_string "fdiv")
15348               ]
15349               (const_string "fop")))
15350    (set_attr "mode" "SF")])
15352 (define_insn "*fop_df_6_i387"
15353   [(set (match_operand:DF 0 "register_operand" "=f,f")
15354         (match_operator:DF 3 "binary_fp_operator"
15355           [(float_extend:DF
15356             (match_operand:SF 1 "register_operand" "0,f"))
15357            (float_extend:DF
15358             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15359   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15360   "* return output_387_binary_op (insn, operands);"
15361   [(set (attr "type")
15362         (cond [(match_operand:DF 3 "mult_operator" "")
15363                  (const_string "fmul")
15364                (match_operand:DF 3 "div_operator" "")
15365                  (const_string "fdiv")
15366               ]
15367               (const_string "fop")))
15368    (set_attr "mode" "SF")])
15370 (define_insn "*fop_xf_comm_i387"
15371   [(set (match_operand:XF 0 "register_operand" "=f")
15372         (match_operator:XF 3 "binary_fp_operator"
15373                         [(match_operand:XF 1 "register_operand" "%0")
15374                          (match_operand:XF 2 "register_operand" "f")]))]
15375   "TARGET_80387
15376    && COMMUTATIVE_ARITH_P (operands[3])"
15377   "* return output_387_binary_op (insn, operands);"
15378   [(set (attr "type")
15379         (if_then_else (match_operand:XF 3 "mult_operator" "")
15380            (const_string "fmul")
15381            (const_string "fop")))
15382    (set_attr "mode" "XF")])
15384 (define_insn "*fop_xf_1_i387"
15385   [(set (match_operand:XF 0 "register_operand" "=f,f")
15386         (match_operator:XF 3 "binary_fp_operator"
15387                         [(match_operand:XF 1 "register_operand" "0,f")
15388                          (match_operand:XF 2 "register_operand" "f,0")]))]
15389   "TARGET_80387
15390    && !COMMUTATIVE_ARITH_P (operands[3])"
15391   "* return output_387_binary_op (insn, operands);"
15392   [(set (attr "type")
15393         (cond [(match_operand:XF 3 "mult_operator" "")
15394                  (const_string "fmul")
15395                (match_operand:XF 3 "div_operator" "")
15396                  (const_string "fdiv")
15397               ]
15398               (const_string "fop")))
15399    (set_attr "mode" "XF")])
15401 (define_insn "*fop_xf_2<mode>_i387"
15402   [(set (match_operand:XF 0 "register_operand" "=f,f")
15403         (match_operator:XF 3 "binary_fp_operator"
15404            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15405             (match_operand:XF 2 "register_operand" "0,0")]))]
15406   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15407   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15408   [(set (attr "type")
15409         (cond [(match_operand:XF 3 "mult_operator" "")
15410                  (const_string "fmul")
15411                (match_operand:XF 3 "div_operator" "")
15412                  (const_string "fdiv")
15413               ]
15414               (const_string "fop")))
15415    (set_attr "fp_int_src" "true")
15416    (set_attr "mode" "<MODE>")])
15418 (define_insn "*fop_xf_3<mode>_i387"
15419   [(set (match_operand:XF 0 "register_operand" "=f,f")
15420         (match_operator:XF 3 "binary_fp_operator"
15421           [(match_operand:XF 1 "register_operand" "0,0")
15422            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15423   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15424   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15425   [(set (attr "type")
15426         (cond [(match_operand:XF 3 "mult_operator" "")
15427                  (const_string "fmul")
15428                (match_operand:XF 3 "div_operator" "")
15429                  (const_string "fdiv")
15430               ]
15431               (const_string "fop")))
15432    (set_attr "fp_int_src" "true")
15433    (set_attr "mode" "<MODE>")])
15435 (define_insn "*fop_xf_4_i387"
15436   [(set (match_operand:XF 0 "register_operand" "=f,f")
15437         (match_operator:XF 3 "binary_fp_operator"
15438            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15439             (match_operand:XF 2 "register_operand" "0,f")]))]
15440   "TARGET_80387"
15441   "* return output_387_binary_op (insn, operands);"
15442   [(set (attr "type")
15443         (cond [(match_operand:XF 3 "mult_operator" "")
15444                  (const_string "fmul")
15445                (match_operand:XF 3 "div_operator" "")
15446                  (const_string "fdiv")
15447               ]
15448               (const_string "fop")))
15449    (set_attr "mode" "SF")])
15451 (define_insn "*fop_xf_5_i387"
15452   [(set (match_operand:XF 0 "register_operand" "=f,f")
15453         (match_operator:XF 3 "binary_fp_operator"
15454           [(match_operand:XF 1 "register_operand" "0,f")
15455            (float_extend:XF
15456             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15457   "TARGET_80387"
15458   "* return output_387_binary_op (insn, operands);"
15459   [(set (attr "type")
15460         (cond [(match_operand:XF 3 "mult_operator" "")
15461                  (const_string "fmul")
15462                (match_operand:XF 3 "div_operator" "")
15463                  (const_string "fdiv")
15464               ]
15465               (const_string "fop")))
15466    (set_attr "mode" "SF")])
15468 (define_insn "*fop_xf_6_i387"
15469   [(set (match_operand:XF 0 "register_operand" "=f,f")
15470         (match_operator:XF 3 "binary_fp_operator"
15471           [(float_extend:XF
15472             (match_operand 1 "register_operand" "0,f"))
15473            (float_extend:XF
15474             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15475   "TARGET_80387"
15476   "* return output_387_binary_op (insn, operands);"
15477   [(set (attr "type")
15478         (cond [(match_operand:XF 3 "mult_operator" "")
15479                  (const_string "fmul")
15480                (match_operand:XF 3 "div_operator" "")
15481                  (const_string "fdiv")
15482               ]
15483               (const_string "fop")))
15484    (set_attr "mode" "SF")])
15486 (define_split
15487   [(set (match_operand 0 "register_operand" "")
15488         (match_operator 3 "binary_fp_operator"
15489            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15490             (match_operand 2 "register_operand" "")]))]
15491   "TARGET_80387 && reload_completed
15492    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15493   [(const_int 0)]
15495   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15496   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15497   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15498                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15499                                           GET_MODE (operands[3]),
15500                                           operands[4],
15501                                           operands[2])));
15502   ix86_free_from_memory (GET_MODE (operands[1]));
15503   DONE;
15506 (define_split
15507   [(set (match_operand 0 "register_operand" "")
15508         (match_operator 3 "binary_fp_operator"
15509            [(match_operand 1 "register_operand" "")
15510             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15511   "TARGET_80387 && reload_completed
15512    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15513   [(const_int 0)]
15515   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15516   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15517   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15518                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15519                                           GET_MODE (operands[3]),
15520                                           operands[1],
15521                                           operands[4])));
15522   ix86_free_from_memory (GET_MODE (operands[2]));
15523   DONE;
15526 ;; FPU special functions.
15528 (define_expand "sqrtsf2"
15529   [(set (match_operand:SF 0 "register_operand" "")
15530         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15531   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15533   if (!TARGET_SSE_MATH)
15534     operands[1] = force_reg (SFmode, operands[1]);
15537 (define_insn "*sqrtsf2_mixed"
15538   [(set (match_operand:SF 0 "register_operand" "=f,x")
15539         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15540   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15541   "@
15542    fsqrt
15543    sqrtss\t{%1, %0|%0, %1}"
15544   [(set_attr "type" "fpspc,sse")
15545    (set_attr "mode" "SF,SF")
15546    (set_attr "athlon_decode" "direct,*")])
15548 (define_insn "*sqrtsf2_sse"
15549   [(set (match_operand:SF 0 "register_operand" "=x")
15550         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15551   "TARGET_SSE_MATH"
15552   "sqrtss\t{%1, %0|%0, %1}"
15553   [(set_attr "type" "sse")
15554    (set_attr "mode" "SF")
15555    (set_attr "athlon_decode" "*")])
15557 (define_insn "*sqrtsf2_i387"
15558   [(set (match_operand:SF 0 "register_operand" "=f")
15559         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15560   "TARGET_USE_FANCY_MATH_387"
15561   "fsqrt"
15562   [(set_attr "type" "fpspc")
15563    (set_attr "mode" "SF")
15564    (set_attr "athlon_decode" "direct")])
15566 (define_expand "sqrtdf2"
15567   [(set (match_operand:DF 0 "register_operand" "")
15568         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15569   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15571   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15572     operands[1] = force_reg (DFmode, operands[1]);
15575 (define_insn "*sqrtdf2_mixed"
15576   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15577         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15578   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15579   "@
15580    fsqrt
15581    sqrtsd\t{%1, %0|%0, %1}"
15582   [(set_attr "type" "fpspc,sse")
15583    (set_attr "mode" "DF,DF")
15584    (set_attr "athlon_decode" "direct,*")])
15586 (define_insn "*sqrtdf2_sse"
15587   [(set (match_operand:DF 0 "register_operand" "=Y")
15588         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15589   "TARGET_SSE2 && TARGET_SSE_MATH"
15590   "sqrtsd\t{%1, %0|%0, %1}"
15591   [(set_attr "type" "sse")
15592    (set_attr "mode" "DF")
15593    (set_attr "athlon_decode" "*")])
15595 (define_insn "*sqrtdf2_i387"
15596   [(set (match_operand:DF 0 "register_operand" "=f")
15597         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15598   "TARGET_USE_FANCY_MATH_387"
15599   "fsqrt"
15600   [(set_attr "type" "fpspc")
15601    (set_attr "mode" "DF")
15602    (set_attr "athlon_decode" "direct")])
15604 (define_insn "*sqrtextendsfdf2_i387"
15605   [(set (match_operand:DF 0 "register_operand" "=f")
15606         (sqrt:DF (float_extend:DF
15607                   (match_operand:SF 1 "register_operand" "0"))))]
15608   "TARGET_USE_FANCY_MATH_387
15609    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15610   "fsqrt"
15611   [(set_attr "type" "fpspc")
15612    (set_attr "mode" "DF")
15613    (set_attr "athlon_decode" "direct")])
15615 (define_insn "sqrtxf2"
15616   [(set (match_operand:XF 0 "register_operand" "=f")
15617         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15618   "TARGET_USE_FANCY_MATH_387"
15619   "fsqrt"
15620   [(set_attr "type" "fpspc")
15621    (set_attr "mode" "XF")
15622    (set_attr "athlon_decode" "direct")])
15624 (define_insn "*sqrtextendsfxf2_i387"
15625   [(set (match_operand:XF 0 "register_operand" "=f")
15626         (sqrt:XF (float_extend:XF
15627                   (match_operand:SF 1 "register_operand" "0"))))]
15628   "TARGET_USE_FANCY_MATH_387"
15629   "fsqrt"
15630   [(set_attr "type" "fpspc")
15631    (set_attr "mode" "XF")
15632    (set_attr "athlon_decode" "direct")])
15634 (define_insn "*sqrtextenddfxf2_i387"
15635   [(set (match_operand:XF 0 "register_operand" "=f")
15636         (sqrt:XF (float_extend:XF
15637                   (match_operand:DF 1 "register_operand" "0"))))]
15638   "TARGET_USE_FANCY_MATH_387"
15639   "fsqrt"
15640   [(set_attr "type" "fpspc")
15641    (set_attr "mode" "XF")
15642    (set_attr "athlon_decode" "direct")])
15644 (define_insn "fpremxf4"
15645   [(set (match_operand:XF 0 "register_operand" "=f")
15646         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15647                     (match_operand:XF 3 "register_operand" "1")]
15648                    UNSPEC_FPREM_F))
15649    (set (match_operand:XF 1 "register_operand" "=u")
15650         (unspec:XF [(match_dup 2) (match_dup 3)]
15651                    UNSPEC_FPREM_U))
15652    (set (reg:CCFP FPSR_REG)
15653         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15654   "TARGET_USE_FANCY_MATH_387"
15655   "fprem"
15656   [(set_attr "type" "fpspc")
15657    (set_attr "mode" "XF")])
15659 (define_expand "fmodsf3"
15660   [(use (match_operand:SF 0 "register_operand" ""))
15661    (use (match_operand:SF 1 "register_operand" ""))
15662    (use (match_operand:SF 2 "register_operand" ""))]
15663   "TARGET_USE_FANCY_MATH_387
15664    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15666   rtx label = gen_label_rtx ();
15668   rtx op1 = gen_reg_rtx (XFmode);
15669   rtx op2 = gen_reg_rtx (XFmode);
15671   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15672   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15674   emit_label (label);
15676   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15677   ix86_emit_fp_unordered_jump (label);
15679   emit_insn (gen_truncxfsf2 (operands[0], op1));
15680   DONE;
15683 (define_expand "fmoddf3"
15684   [(use (match_operand:DF 0 "register_operand" ""))
15685    (use (match_operand:DF 1 "register_operand" ""))
15686    (use (match_operand:DF 2 "register_operand" ""))]
15687   "TARGET_USE_FANCY_MATH_387
15688    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15690   rtx label = gen_label_rtx ();
15692   rtx op1 = gen_reg_rtx (XFmode);
15693   rtx op2 = gen_reg_rtx (XFmode);
15695   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15696   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15698   emit_label (label);
15700   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15701   ix86_emit_fp_unordered_jump (label);
15703   emit_insn (gen_truncxfdf2 (operands[0], op1));
15704   DONE;
15707 (define_expand "fmodxf3"
15708   [(use (match_operand:XF 0 "register_operand" ""))
15709    (use (match_operand:XF 1 "register_operand" ""))
15710    (use (match_operand:XF 2 "register_operand" ""))]
15711   "TARGET_USE_FANCY_MATH_387"
15713   rtx label = gen_label_rtx ();
15715   emit_label (label);
15717   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15718                            operands[1], operands[2]));
15719   ix86_emit_fp_unordered_jump (label);
15721   emit_move_insn (operands[0], operands[1]);
15722   DONE;
15725 (define_insn "fprem1xf4"
15726   [(set (match_operand:XF 0 "register_operand" "=f")
15727         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15728                     (match_operand:XF 3 "register_operand" "1")]
15729                    UNSPEC_FPREM1_F))
15730    (set (match_operand:XF 1 "register_operand" "=u")
15731         (unspec:XF [(match_dup 2) (match_dup 3)]
15732                    UNSPEC_FPREM1_U))
15733    (set (reg:CCFP FPSR_REG)
15734         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15735   "TARGET_USE_FANCY_MATH_387"
15736   "fprem1"
15737   [(set_attr "type" "fpspc")
15738    (set_attr "mode" "XF")])
15740 (define_expand "remaindersf3"
15741   [(use (match_operand:SF 0 "register_operand" ""))
15742    (use (match_operand:SF 1 "register_operand" ""))
15743    (use (match_operand:SF 2 "register_operand" ""))]
15744   "TARGET_USE_FANCY_MATH_387
15745    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
15747   rtx label = gen_label_rtx ();
15749   rtx op1 = gen_reg_rtx (XFmode);
15750   rtx op2 = gen_reg_rtx (XFmode);
15752   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15753   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15755   emit_label (label);
15757   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15758   ix86_emit_fp_unordered_jump (label);
15760   emit_insn (gen_truncxfsf2 (operands[0], op1));
15761   DONE;
15764 (define_expand "remainderdf3"
15765   [(use (match_operand:DF 0 "register_operand" ""))
15766    (use (match_operand:DF 1 "register_operand" ""))
15767    (use (match_operand:DF 2 "register_operand" ""))]
15768   "TARGET_USE_FANCY_MATH_387
15769    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15771   rtx label = gen_label_rtx ();
15773   rtx op1 = gen_reg_rtx (XFmode);
15774   rtx op2 = gen_reg_rtx (XFmode);
15776   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15777   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15779   emit_label (label);
15781   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15782   ix86_emit_fp_unordered_jump (label);
15784   emit_insn (gen_truncxfdf2 (operands[0], op1));
15785   DONE;
15788 (define_expand "remainderxf3"
15789   [(use (match_operand:XF 0 "register_operand" ""))
15790    (use (match_operand:XF 1 "register_operand" ""))
15791    (use (match_operand:XF 2 "register_operand" ""))]
15792   "TARGET_USE_FANCY_MATH_387"
15794   rtx label = gen_label_rtx ();
15796   emit_label (label);
15798   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15799                             operands[1], operands[2]));
15800   ix86_emit_fp_unordered_jump (label);
15802   emit_move_insn (operands[0], operands[1]);
15803   DONE;
15806 (define_insn "*sindf2"
15807   [(set (match_operand:DF 0 "register_operand" "=f")
15808         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15809   "TARGET_USE_FANCY_MATH_387
15810    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15811    && flag_unsafe_math_optimizations"
15812   "fsin"
15813   [(set_attr "type" "fpspc")
15814    (set_attr "mode" "DF")])
15816 (define_insn "*sinsf2"
15817   [(set (match_operand:SF 0 "register_operand" "=f")
15818         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15819   "TARGET_USE_FANCY_MATH_387
15820    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15821    && flag_unsafe_math_optimizations"
15822   "fsin"
15823   [(set_attr "type" "fpspc")
15824    (set_attr "mode" "SF")])
15826 (define_insn "*sinextendsfdf2"
15827   [(set (match_operand:DF 0 "register_operand" "=f")
15828         (unspec:DF [(float_extend:DF
15829                      (match_operand:SF 1 "register_operand" "0"))]
15830                    UNSPEC_SIN))]
15831   "TARGET_USE_FANCY_MATH_387
15832    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15833    && flag_unsafe_math_optimizations"
15834   "fsin"
15835   [(set_attr "type" "fpspc")
15836    (set_attr "mode" "DF")])
15838 (define_insn "*sinxf2"
15839   [(set (match_operand:XF 0 "register_operand" "=f")
15840         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15841   "TARGET_USE_FANCY_MATH_387
15842    && flag_unsafe_math_optimizations"
15843   "fsin"
15844   [(set_attr "type" "fpspc")
15845    (set_attr "mode" "XF")])
15847 (define_insn "*cosdf2"
15848   [(set (match_operand:DF 0 "register_operand" "=f")
15849         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15850   "TARGET_USE_FANCY_MATH_387
15851    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15852    && flag_unsafe_math_optimizations"
15853   "fcos"
15854   [(set_attr "type" "fpspc")
15855    (set_attr "mode" "DF")])
15857 (define_insn "*cossf2"
15858   [(set (match_operand:SF 0 "register_operand" "=f")
15859         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15860   "TARGET_USE_FANCY_MATH_387
15861    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15862    && flag_unsafe_math_optimizations"
15863   "fcos"
15864   [(set_attr "type" "fpspc")
15865    (set_attr "mode" "SF")])
15867 (define_insn "*cosextendsfdf2"
15868   [(set (match_operand:DF 0 "register_operand" "=f")
15869         (unspec:DF [(float_extend:DF
15870                      (match_operand:SF 1 "register_operand" "0"))]
15871                    UNSPEC_COS))]
15872   "TARGET_USE_FANCY_MATH_387
15873    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15874    && flag_unsafe_math_optimizations"
15875   "fcos"
15876   [(set_attr "type" "fpspc")
15877    (set_attr "mode" "DF")])
15879 (define_insn "*cosxf2"
15880   [(set (match_operand:XF 0 "register_operand" "=f")
15881         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15882   "TARGET_USE_FANCY_MATH_387
15883    && flag_unsafe_math_optimizations"
15884   "fcos"
15885   [(set_attr "type" "fpspc")
15886    (set_attr "mode" "XF")])
15888 ;; With sincos pattern defined, sin and cos builtin function will be
15889 ;; expanded to sincos pattern with one of its outputs left unused.
15890 ;; Cse pass  will detected, if two sincos patterns can be combined,
15891 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15892 ;; depending on the unused output.
15894 (define_insn "sincosdf3"
15895   [(set (match_operand:DF 0 "register_operand" "=f")
15896         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15897                    UNSPEC_SINCOS_COS))
15898    (set (match_operand:DF 1 "register_operand" "=u")
15899         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15900   "TARGET_USE_FANCY_MATH_387
15901    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15902    && flag_unsafe_math_optimizations"
15903   "fsincos"
15904   [(set_attr "type" "fpspc")
15905    (set_attr "mode" "DF")])
15907 (define_split
15908   [(set (match_operand:DF 0 "register_operand" "")
15909         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15910                    UNSPEC_SINCOS_COS))
15911    (set (match_operand:DF 1 "register_operand" "")
15912         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15913   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15914    && !reload_completed && !reload_in_progress"
15915   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15916   "")
15918 (define_split
15919   [(set (match_operand:DF 0 "register_operand" "")
15920         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15921                    UNSPEC_SINCOS_COS))
15922    (set (match_operand:DF 1 "register_operand" "")
15923         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15924   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15925    && !reload_completed && !reload_in_progress"
15926   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15927   "")
15929 (define_insn "sincossf3"
15930   [(set (match_operand:SF 0 "register_operand" "=f")
15931         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15932                    UNSPEC_SINCOS_COS))
15933    (set (match_operand:SF 1 "register_operand" "=u")
15934         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15935   "TARGET_USE_FANCY_MATH_387
15936    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15937    && flag_unsafe_math_optimizations"
15938   "fsincos"
15939   [(set_attr "type" "fpspc")
15940    (set_attr "mode" "SF")])
15942 (define_split
15943   [(set (match_operand:SF 0 "register_operand" "")
15944         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15945                    UNSPEC_SINCOS_COS))
15946    (set (match_operand:SF 1 "register_operand" "")
15947         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15948   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15949    && !reload_completed && !reload_in_progress"
15950   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15951   "")
15953 (define_split
15954   [(set (match_operand:SF 0 "register_operand" "")
15955         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15956                    UNSPEC_SINCOS_COS))
15957    (set (match_operand:SF 1 "register_operand" "")
15958         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15959   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15960    && !reload_completed && !reload_in_progress"
15961   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15962   "")
15964 (define_insn "*sincosextendsfdf3"
15965   [(set (match_operand:DF 0 "register_operand" "=f")
15966         (unspec:DF [(float_extend:DF
15967                      (match_operand:SF 2 "register_operand" "0"))]
15968                    UNSPEC_SINCOS_COS))
15969    (set (match_operand:DF 1 "register_operand" "=u")
15970         (unspec:DF [(float_extend:DF
15971                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15972   "TARGET_USE_FANCY_MATH_387
15973    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15974    && flag_unsafe_math_optimizations"
15975   "fsincos"
15976   [(set_attr "type" "fpspc")
15977    (set_attr "mode" "DF")])
15979 (define_split
15980   [(set (match_operand:DF 0 "register_operand" "")
15981         (unspec:DF [(float_extend:DF
15982                      (match_operand:SF 2 "register_operand" ""))]
15983                    UNSPEC_SINCOS_COS))
15984    (set (match_operand:DF 1 "register_operand" "")
15985         (unspec:DF [(float_extend:DF
15986                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15987   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15988    && !reload_completed && !reload_in_progress"
15989   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15990                                    (match_dup 2))] UNSPEC_SIN))]
15991   "")
15993 (define_split
15994   [(set (match_operand:DF 0 "register_operand" "")
15995         (unspec:DF [(float_extend:DF
15996                      (match_operand:SF 2 "register_operand" ""))]
15997                    UNSPEC_SINCOS_COS))
15998    (set (match_operand:DF 1 "register_operand" "")
15999         (unspec:DF [(float_extend:DF
16000                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
16001   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16002    && !reload_completed && !reload_in_progress"
16003   [(set (match_dup 0) (unspec:DF [(float_extend:DF
16004                                    (match_dup 2))] UNSPEC_COS))]
16005   "")
16007 (define_insn "sincosxf3"
16008   [(set (match_operand:XF 0 "register_operand" "=f")
16009         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16010                    UNSPEC_SINCOS_COS))
16011    (set (match_operand:XF 1 "register_operand" "=u")
16012         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16013   "TARGET_USE_FANCY_MATH_387
16014    && flag_unsafe_math_optimizations"
16015   "fsincos"
16016   [(set_attr "type" "fpspc")
16017    (set_attr "mode" "XF")])
16019 (define_split
16020   [(set (match_operand:XF 0 "register_operand" "")
16021         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16022                    UNSPEC_SINCOS_COS))
16023    (set (match_operand:XF 1 "register_operand" "")
16024         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16025   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16026    && !reload_completed && !reload_in_progress"
16027   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16028   "")
16030 (define_split
16031   [(set (match_operand:XF 0 "register_operand" "")
16032         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16033                    UNSPEC_SINCOS_COS))
16034    (set (match_operand:XF 1 "register_operand" "")
16035         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16036   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16037    && !reload_completed && !reload_in_progress"
16038   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16039   "")
16041 (define_insn "*tandf3_1"
16042   [(set (match_operand:DF 0 "register_operand" "=f")
16043         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16044                    UNSPEC_TAN_ONE))
16045    (set (match_operand:DF 1 "register_operand" "=u")
16046         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16047   "TARGET_USE_FANCY_MATH_387
16048    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16049    && flag_unsafe_math_optimizations"
16050   "fptan"
16051   [(set_attr "type" "fpspc")
16052    (set_attr "mode" "DF")])
16054 ;; optimize sequence: fptan
16055 ;;                    fstp    %st(0)
16056 ;;                    fld1
16057 ;; into fptan insn.
16059 (define_peephole2
16060   [(parallel[(set (match_operand:DF 0 "register_operand" "")
16061                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16062                              UNSPEC_TAN_ONE))
16063              (set (match_operand:DF 1 "register_operand" "")
16064                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16065    (set (match_dup 0)
16066         (match_operand:DF 3 "immediate_operand" ""))]
16067   "standard_80387_constant_p (operands[3]) == 2"
16068   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16069              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16070   "")
16072 (define_expand "tandf2"
16073   [(parallel [(set (match_dup 2)
16074                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16075                               UNSPEC_TAN_ONE))
16076               (set (match_operand:DF 0 "register_operand" "")
16077                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16078   "TARGET_USE_FANCY_MATH_387
16079    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16080    && flag_unsafe_math_optimizations"
16082   operands[2] = gen_reg_rtx (DFmode);
16085 (define_insn "*tansf3_1"
16086   [(set (match_operand:SF 0 "register_operand" "=f")
16087         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16088                    UNSPEC_TAN_ONE))
16089    (set (match_operand:SF 1 "register_operand" "=u")
16090         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16091   "TARGET_USE_FANCY_MATH_387
16092    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16093    && flag_unsafe_math_optimizations"
16094   "fptan"
16095   [(set_attr "type" "fpspc")
16096    (set_attr "mode" "SF")])
16098 ;; optimize sequence: fptan
16099 ;;                    fstp    %st(0)
16100 ;;                    fld1
16101 ;; into fptan insn.
16103 (define_peephole2
16104   [(parallel[(set (match_operand:SF 0 "register_operand" "")
16105                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16106                              UNSPEC_TAN_ONE))
16107              (set (match_operand:SF 1 "register_operand" "")
16108                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16109    (set (match_dup 0)
16110         (match_operand:SF 3 "immediate_operand" ""))]
16111   "standard_80387_constant_p (operands[3]) == 2"
16112   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16113              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16114   "")
16116 (define_expand "tansf2"
16117   [(parallel [(set (match_dup 2)
16118                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16119                               UNSPEC_TAN_ONE))
16120               (set (match_operand:SF 0 "register_operand" "")
16121                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16122   "TARGET_USE_FANCY_MATH_387
16123    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16124    && flag_unsafe_math_optimizations"
16126   operands[2] = gen_reg_rtx (SFmode);
16129 (define_insn "*tanxf3_1"
16130   [(set (match_operand:XF 0 "register_operand" "=f")
16131         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16132                    UNSPEC_TAN_ONE))
16133    (set (match_operand:XF 1 "register_operand" "=u")
16134         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16135   "TARGET_USE_FANCY_MATH_387
16136    && flag_unsafe_math_optimizations"
16137   "fptan"
16138   [(set_attr "type" "fpspc")
16139    (set_attr "mode" "XF")])
16141 ;; optimize sequence: fptan
16142 ;;                    fstp    %st(0)
16143 ;;                    fld1
16144 ;; into fptan insn.
16146 (define_peephole2
16147   [(parallel[(set (match_operand:XF 0 "register_operand" "")
16148                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16149                              UNSPEC_TAN_ONE))
16150              (set (match_operand:XF 1 "register_operand" "")
16151                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16152    (set (match_dup 0)
16153         (match_operand:XF 3 "immediate_operand" ""))]
16154   "standard_80387_constant_p (operands[3]) == 2"
16155   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16156              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16157   "")
16159 (define_expand "tanxf2"
16160   [(parallel [(set (match_dup 2)
16161                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16162                               UNSPEC_TAN_ONE))
16163               (set (match_operand:XF 0 "register_operand" "")
16164                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16165   "TARGET_USE_FANCY_MATH_387
16166    && flag_unsafe_math_optimizations"
16168   operands[2] = gen_reg_rtx (XFmode);
16171 (define_insn "atan2df3_1"
16172   [(set (match_operand:DF 0 "register_operand" "=f")
16173         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16174                     (match_operand:DF 1 "register_operand" "u")]
16175                    UNSPEC_FPATAN))
16176    (clobber (match_scratch:DF 3 "=1"))]
16177   "TARGET_USE_FANCY_MATH_387
16178    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16179    && flag_unsafe_math_optimizations"
16180   "fpatan"
16181   [(set_attr "type" "fpspc")
16182    (set_attr "mode" "DF")])
16184 (define_expand "atan2df3"
16185   [(use (match_operand:DF 0 "register_operand" ""))
16186    (use (match_operand:DF 2 "register_operand" ""))
16187    (use (match_operand:DF 1 "register_operand" ""))]
16188   "TARGET_USE_FANCY_MATH_387
16189    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16190    && flag_unsafe_math_optimizations"
16192   rtx copy = gen_reg_rtx (DFmode);
16193   emit_move_insn (copy, operands[1]);
16194   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16195   DONE;
16198 (define_expand "atandf2"
16199   [(parallel [(set (match_operand:DF 0 "register_operand" "")
16200                    (unspec:DF [(match_dup 2)
16201                                (match_operand:DF 1 "register_operand" "")]
16202                     UNSPEC_FPATAN))
16203               (clobber (match_scratch:DF 3 ""))])]
16204   "TARGET_USE_FANCY_MATH_387
16205    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16206    && flag_unsafe_math_optimizations"
16208   operands[2] = gen_reg_rtx (DFmode);
16209   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16212 (define_insn "atan2sf3_1"
16213   [(set (match_operand:SF 0 "register_operand" "=f")
16214         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16215                     (match_operand:SF 1 "register_operand" "u")]
16216                    UNSPEC_FPATAN))
16217    (clobber (match_scratch:SF 3 "=1"))]
16218   "TARGET_USE_FANCY_MATH_387
16219    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16220    && flag_unsafe_math_optimizations"
16221   "fpatan"
16222   [(set_attr "type" "fpspc")
16223    (set_attr "mode" "SF")])
16225 (define_expand "atan2sf3"
16226   [(use (match_operand:SF 0 "register_operand" ""))
16227    (use (match_operand:SF 2 "register_operand" ""))
16228    (use (match_operand:SF 1 "register_operand" ""))]
16229   "TARGET_USE_FANCY_MATH_387
16230    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16231    && flag_unsafe_math_optimizations"
16233   rtx copy = gen_reg_rtx (SFmode);
16234   emit_move_insn (copy, operands[1]);
16235   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16236   DONE;
16239 (define_expand "atansf2"
16240   [(parallel [(set (match_operand:SF 0 "register_operand" "")
16241                    (unspec:SF [(match_dup 2)
16242                                (match_operand:SF 1 "register_operand" "")]
16243                     UNSPEC_FPATAN))
16244               (clobber (match_scratch:SF 3 ""))])]
16245   "TARGET_USE_FANCY_MATH_387
16246    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16247    && flag_unsafe_math_optimizations"
16249   operands[2] = gen_reg_rtx (SFmode);
16250   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16253 (define_insn "atan2xf3_1"
16254   [(set (match_operand:XF 0 "register_operand" "=f")
16255         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16256                     (match_operand:XF 1 "register_operand" "u")]
16257                    UNSPEC_FPATAN))
16258    (clobber (match_scratch:XF 3 "=1"))]
16259   "TARGET_USE_FANCY_MATH_387
16260    && flag_unsafe_math_optimizations"
16261   "fpatan"
16262   [(set_attr "type" "fpspc")
16263    (set_attr "mode" "XF")])
16265 (define_expand "atan2xf3"
16266   [(use (match_operand:XF 0 "register_operand" ""))
16267    (use (match_operand:XF 2 "register_operand" ""))
16268    (use (match_operand:XF 1 "register_operand" ""))]
16269   "TARGET_USE_FANCY_MATH_387
16270    && flag_unsafe_math_optimizations"
16272   rtx copy = gen_reg_rtx (XFmode);
16273   emit_move_insn (copy, operands[1]);
16274   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16275   DONE;
16278 (define_expand "atanxf2"
16279   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16280                    (unspec:XF [(match_dup 2)
16281                                (match_operand:XF 1 "register_operand" "")]
16282                     UNSPEC_FPATAN))
16283               (clobber (match_scratch:XF 3 ""))])]
16284   "TARGET_USE_FANCY_MATH_387
16285    && flag_unsafe_math_optimizations"
16287   operands[2] = gen_reg_rtx (XFmode);
16288   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16291 (define_expand "asindf2"
16292   [(set (match_dup 2)
16293         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16294    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16295    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16296    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16297    (parallel [(set (match_dup 7)
16298                    (unspec:XF [(match_dup 6) (match_dup 2)]
16299                               UNSPEC_FPATAN))
16300               (clobber (match_scratch:XF 8 ""))])
16301    (set (match_operand:DF 0 "register_operand" "")
16302         (float_truncate:DF (match_dup 7)))]
16303   "TARGET_USE_FANCY_MATH_387
16304    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16305    && flag_unsafe_math_optimizations && !optimize_size"
16307   int i;
16309   for (i=2; i<8; i++)
16310     operands[i] = gen_reg_rtx (XFmode);
16312   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16315 (define_expand "asinsf2"
16316   [(set (match_dup 2)
16317         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16318    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16319    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16320    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16321    (parallel [(set (match_dup 7)
16322                    (unspec:XF [(match_dup 6) (match_dup 2)]
16323                               UNSPEC_FPATAN))
16324               (clobber (match_scratch:XF 8 ""))])
16325    (set (match_operand:SF 0 "register_operand" "")
16326         (float_truncate:SF (match_dup 7)))]
16327   "TARGET_USE_FANCY_MATH_387
16328    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16329    && flag_unsafe_math_optimizations && !optimize_size"
16331   int i;
16333   for (i=2; i<8; i++)
16334     operands[i] = gen_reg_rtx (XFmode);
16336   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16339 (define_expand "asinxf2"
16340   [(set (match_dup 2)
16341         (mult:XF (match_operand:XF 1 "register_operand" "")
16342                  (match_dup 1)))
16343    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16344    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16345    (parallel [(set (match_operand:XF 0 "register_operand" "")
16346                    (unspec:XF [(match_dup 5) (match_dup 1)]
16347                               UNSPEC_FPATAN))
16348               (clobber (match_scratch:XF 6 ""))])]
16349   "TARGET_USE_FANCY_MATH_387
16350    && flag_unsafe_math_optimizations && !optimize_size"
16352   int i;
16354   for (i=2; i<6; i++)
16355     operands[i] = gen_reg_rtx (XFmode);
16357   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16360 (define_expand "acosdf2"
16361   [(set (match_dup 2)
16362         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16363    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16364    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16365    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16366    (parallel [(set (match_dup 7)
16367                    (unspec:XF [(match_dup 2) (match_dup 6)]
16368                               UNSPEC_FPATAN))
16369               (clobber (match_scratch:XF 8 ""))])
16370    (set (match_operand:DF 0 "register_operand" "")
16371         (float_truncate:DF (match_dup 7)))]
16372   "TARGET_USE_FANCY_MATH_387
16373    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16374    && flag_unsafe_math_optimizations && !optimize_size"
16376   int i;
16378   for (i=2; i<8; i++)
16379     operands[i] = gen_reg_rtx (XFmode);
16381   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16384 (define_expand "acossf2"
16385   [(set (match_dup 2)
16386         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16387    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16388    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16389    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16390    (parallel [(set (match_dup 7)
16391                    (unspec:XF [(match_dup 2) (match_dup 6)]
16392                               UNSPEC_FPATAN))
16393               (clobber (match_scratch:XF 8 ""))])
16394    (set (match_operand:SF 0 "register_operand" "")
16395         (float_truncate:SF (match_dup 7)))]
16396   "TARGET_USE_FANCY_MATH_387
16397    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16398    && flag_unsafe_math_optimizations && !optimize_size"
16400   int i;
16402   for (i=2; i<8; i++)
16403     operands[i] = gen_reg_rtx (XFmode);
16405   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16408 (define_expand "acosxf2"
16409   [(set (match_dup 2)
16410         (mult:XF (match_operand:XF 1 "register_operand" "")
16411                  (match_dup 1)))
16412    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16413    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16414    (parallel [(set (match_operand:XF 0 "register_operand" "")
16415                    (unspec:XF [(match_dup 1) (match_dup 5)]
16416                               UNSPEC_FPATAN))
16417               (clobber (match_scratch:XF 6 ""))])]
16418   "TARGET_USE_FANCY_MATH_387
16419    && flag_unsafe_math_optimizations && !optimize_size"
16421   int i;
16423   for (i=2; i<6; i++)
16424     operands[i] = gen_reg_rtx (XFmode);
16426   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16429 (define_insn "fyl2x_xf3"
16430   [(set (match_operand:XF 0 "register_operand" "=f")
16431         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16432                     (match_operand:XF 1 "register_operand" "u")]
16433                    UNSPEC_FYL2X))
16434    (clobber (match_scratch:XF 3 "=1"))]
16435   "TARGET_USE_FANCY_MATH_387
16436    && flag_unsafe_math_optimizations"
16437   "fyl2x"
16438   [(set_attr "type" "fpspc")
16439    (set_attr "mode" "XF")])
16441 (define_expand "logsf2"
16442   [(set (match_dup 2)
16443         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16444    (parallel [(set (match_dup 4)
16445                    (unspec:XF [(match_dup 2)
16446                                (match_dup 3)] UNSPEC_FYL2X))
16447               (clobber (match_scratch:XF 5 ""))])
16448    (set (match_operand:SF 0 "register_operand" "")
16449         (float_truncate:SF (match_dup 4)))]
16450   "TARGET_USE_FANCY_MATH_387
16451    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16452    && flag_unsafe_math_optimizations"
16454   rtx temp;
16456   operands[2] = gen_reg_rtx (XFmode);
16457   operands[3] = gen_reg_rtx (XFmode);
16458   operands[4] = gen_reg_rtx (XFmode);
16460   temp = standard_80387_constant_rtx (4); /* fldln2 */
16461   emit_move_insn (operands[3], temp);
16464 (define_expand "logdf2"
16465   [(set (match_dup 2)
16466         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16467    (parallel [(set (match_dup 4)
16468                    (unspec:XF [(match_dup 2)
16469                                (match_dup 3)] UNSPEC_FYL2X))
16470               (clobber (match_scratch:XF 5 ""))])
16471    (set (match_operand:DF 0 "register_operand" "")
16472         (float_truncate:DF (match_dup 4)))]
16473   "TARGET_USE_FANCY_MATH_387
16474    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16475    && flag_unsafe_math_optimizations"
16477   rtx temp;
16479   operands[2] = gen_reg_rtx (XFmode);
16480   operands[3] = gen_reg_rtx (XFmode);
16481   operands[4] = gen_reg_rtx (XFmode);
16483   temp = standard_80387_constant_rtx (4); /* fldln2 */
16484   emit_move_insn (operands[3], temp);
16487 (define_expand "logxf2"
16488   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16489                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16490                                (match_dup 2)] UNSPEC_FYL2X))
16491               (clobber (match_scratch:XF 3 ""))])]
16492   "TARGET_USE_FANCY_MATH_387
16493    && flag_unsafe_math_optimizations"
16495   rtx temp;
16497   operands[2] = gen_reg_rtx (XFmode);
16498   temp = standard_80387_constant_rtx (4); /* fldln2 */
16499   emit_move_insn (operands[2], temp);
16502 (define_expand "log10sf2"
16503   [(set (match_dup 2)
16504         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16505    (parallel [(set (match_dup 4)
16506                    (unspec:XF [(match_dup 2)
16507                                (match_dup 3)] UNSPEC_FYL2X))
16508               (clobber (match_scratch:XF 5 ""))])
16509    (set (match_operand:SF 0 "register_operand" "")
16510         (float_truncate:SF (match_dup 4)))]
16511   "TARGET_USE_FANCY_MATH_387
16512    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16513    && flag_unsafe_math_optimizations"
16515   rtx temp;
16517   operands[2] = gen_reg_rtx (XFmode);
16518   operands[3] = gen_reg_rtx (XFmode);
16519   operands[4] = gen_reg_rtx (XFmode);
16521   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16522   emit_move_insn (operands[3], temp);
16525 (define_expand "log10df2"
16526   [(set (match_dup 2)
16527         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16528    (parallel [(set (match_dup 4)
16529                    (unspec:XF [(match_dup 2)
16530                                (match_dup 3)] UNSPEC_FYL2X))
16531               (clobber (match_scratch:XF 5 ""))])
16532    (set (match_operand:DF 0 "register_operand" "")
16533         (float_truncate:DF (match_dup 4)))]
16534   "TARGET_USE_FANCY_MATH_387
16535    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16536    && flag_unsafe_math_optimizations"
16538   rtx temp;
16540   operands[2] = gen_reg_rtx (XFmode);
16541   operands[3] = gen_reg_rtx (XFmode);
16542   operands[4] = gen_reg_rtx (XFmode);
16544   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16545   emit_move_insn (operands[3], temp);
16548 (define_expand "log10xf2"
16549   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16550                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16551                                (match_dup 2)] UNSPEC_FYL2X))
16552               (clobber (match_scratch:XF 3 ""))])]
16553   "TARGET_USE_FANCY_MATH_387
16554    && flag_unsafe_math_optimizations"
16556   rtx temp;
16558   operands[2] = gen_reg_rtx (XFmode);
16559   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16560   emit_move_insn (operands[2], temp);
16563 (define_expand "log2sf2"
16564   [(set (match_dup 2)
16565         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16566    (parallel [(set (match_dup 4)
16567                    (unspec:XF [(match_dup 2)
16568                                (match_dup 3)] UNSPEC_FYL2X))
16569               (clobber (match_scratch:XF 5 ""))])
16570    (set (match_operand:SF 0 "register_operand" "")
16571         (float_truncate:SF (match_dup 4)))]
16572   "TARGET_USE_FANCY_MATH_387
16573    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16574    && flag_unsafe_math_optimizations"
16576   operands[2] = gen_reg_rtx (XFmode);
16577   operands[3] = gen_reg_rtx (XFmode);
16578   operands[4] = gen_reg_rtx (XFmode);
16580   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16583 (define_expand "log2df2"
16584   [(set (match_dup 2)
16585         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16586    (parallel [(set (match_dup 4)
16587                    (unspec:XF [(match_dup 2)
16588                                (match_dup 3)] UNSPEC_FYL2X))
16589               (clobber (match_scratch:XF 5 ""))])
16590    (set (match_operand:DF 0 "register_operand" "")
16591         (float_truncate:DF (match_dup 4)))]
16592   "TARGET_USE_FANCY_MATH_387
16593    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16594    && flag_unsafe_math_optimizations"
16596   operands[2] = gen_reg_rtx (XFmode);
16597   operands[3] = gen_reg_rtx (XFmode);
16598   operands[4] = gen_reg_rtx (XFmode);
16600   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16603 (define_expand "log2xf2"
16604   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16605                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16606                                (match_dup 2)] UNSPEC_FYL2X))
16607               (clobber (match_scratch:XF 3 ""))])]
16608   "TARGET_USE_FANCY_MATH_387
16609    && flag_unsafe_math_optimizations"
16611   operands[2] = gen_reg_rtx (XFmode);
16612   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16615 (define_insn "fyl2xp1_xf3"
16616   [(set (match_operand:XF 0 "register_operand" "=f")
16617         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16618                     (match_operand:XF 1 "register_operand" "u")]
16619                    UNSPEC_FYL2XP1))
16620    (clobber (match_scratch:XF 3 "=1"))]
16621   "TARGET_USE_FANCY_MATH_387
16622    && flag_unsafe_math_optimizations"
16623   "fyl2xp1"
16624   [(set_attr "type" "fpspc")
16625    (set_attr "mode" "XF")])
16627 (define_expand "log1psf2"
16628   [(use (match_operand:SF 0 "register_operand" ""))
16629    (use (match_operand:SF 1 "register_operand" ""))]
16630   "TARGET_USE_FANCY_MATH_387
16631    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16632    && flag_unsafe_math_optimizations && !optimize_size"
16634   rtx op0 = gen_reg_rtx (XFmode);
16635   rtx op1 = gen_reg_rtx (XFmode);
16637   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16638   ix86_emit_i387_log1p (op0, op1);
16639   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16640   DONE;
16643 (define_expand "log1pdf2"
16644   [(use (match_operand:DF 0 "register_operand" ""))
16645    (use (match_operand:DF 1 "register_operand" ""))]
16646   "TARGET_USE_FANCY_MATH_387
16647    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16648    && flag_unsafe_math_optimizations && !optimize_size"
16650   rtx op0 = gen_reg_rtx (XFmode);
16651   rtx op1 = gen_reg_rtx (XFmode);
16653   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16654   ix86_emit_i387_log1p (op0, op1);
16655   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16656   DONE;
16659 (define_expand "log1pxf2"
16660   [(use (match_operand:XF 0 "register_operand" ""))
16661    (use (match_operand:XF 1 "register_operand" ""))]
16662   "TARGET_USE_FANCY_MATH_387
16663    && flag_unsafe_math_optimizations && !optimize_size"
16665   ix86_emit_i387_log1p (operands[0], operands[1]);
16666   DONE;
16669 (define_insn "*fxtractxf3"
16670   [(set (match_operand:XF 0 "register_operand" "=f")
16671         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16672                    UNSPEC_XTRACT_FRACT))
16673    (set (match_operand:XF 1 "register_operand" "=u")
16674         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16675   "TARGET_USE_FANCY_MATH_387
16676    && flag_unsafe_math_optimizations"
16677   "fxtract"
16678   [(set_attr "type" "fpspc")
16679    (set_attr "mode" "XF")])
16681 (define_expand "logbsf2"
16682   [(set (match_dup 2)
16683         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16684    (parallel [(set (match_dup 3)
16685                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16686               (set (match_dup 4)
16687                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16688    (set (match_operand:SF 0 "register_operand" "")
16689         (float_truncate:SF (match_dup 4)))]
16690   "TARGET_USE_FANCY_MATH_387
16691    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16692    && flag_unsafe_math_optimizations"
16694   operands[2] = gen_reg_rtx (XFmode);
16695   operands[3] = gen_reg_rtx (XFmode);
16696   operands[4] = gen_reg_rtx (XFmode);
16699 (define_expand "logbdf2"
16700   [(set (match_dup 2)
16701         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16702    (parallel [(set (match_dup 3)
16703                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16704               (set (match_dup 4)
16705                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16706    (set (match_operand:DF 0 "register_operand" "")
16707         (float_truncate:DF (match_dup 4)))]
16708   "TARGET_USE_FANCY_MATH_387
16709    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16710    && flag_unsafe_math_optimizations"
16712   operands[2] = gen_reg_rtx (XFmode);
16713   operands[3] = gen_reg_rtx (XFmode);
16714   operands[4] = gen_reg_rtx (XFmode);
16717 (define_expand "logbxf2"
16718   [(parallel [(set (match_dup 2)
16719                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16720                               UNSPEC_XTRACT_FRACT))
16721               (set (match_operand:XF 0 "register_operand" "")
16722                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16723   "TARGET_USE_FANCY_MATH_387
16724    && flag_unsafe_math_optimizations"
16726   operands[2] = gen_reg_rtx (XFmode);
16729 (define_expand "ilogbsi2"
16730   [(parallel [(set (match_dup 2)
16731                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16732                               UNSPEC_XTRACT_FRACT))
16733               (set (match_operand:XF 3 "register_operand" "")
16734                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16735    (parallel [(set (match_operand:SI 0 "register_operand" "")
16736                    (fix:SI (match_dup 3)))
16737               (clobber (reg:CC FLAGS_REG))])]
16738   "TARGET_USE_FANCY_MATH_387
16739    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16740    && flag_unsafe_math_optimizations && !optimize_size"
16742   operands[2] = gen_reg_rtx (XFmode);
16743   operands[3] = gen_reg_rtx (XFmode);
16746 (define_insn "*f2xm1xf2"
16747   [(set (match_operand:XF 0 "register_operand" "=f")
16748         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16749          UNSPEC_F2XM1))]
16750   "TARGET_USE_FANCY_MATH_387
16751    && flag_unsafe_math_optimizations"
16752   "f2xm1"
16753   [(set_attr "type" "fpspc")
16754    (set_attr "mode" "XF")])
16756 (define_insn "*fscalexf4"
16757   [(set (match_operand:XF 0 "register_operand" "=f")
16758         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16759                     (match_operand:XF 3 "register_operand" "1")]
16760                    UNSPEC_FSCALE_FRACT))
16761    (set (match_operand:XF 1 "register_operand" "=u")
16762         (unspec:XF [(match_dup 2) (match_dup 3)]
16763                    UNSPEC_FSCALE_EXP))]
16764   "TARGET_USE_FANCY_MATH_387
16765    && flag_unsafe_math_optimizations"
16766   "fscale"
16767   [(set_attr "type" "fpspc")
16768    (set_attr "mode" "XF")])
16770 (define_expand "expsf2"
16771   [(set (match_dup 2)
16772         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16773    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16774    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16775    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16776    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16777    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16778    (parallel [(set (match_dup 10)
16779                    (unspec:XF [(match_dup 9) (match_dup 5)]
16780                               UNSPEC_FSCALE_FRACT))
16781               (set (match_dup 11)
16782                    (unspec:XF [(match_dup 9) (match_dup 5)]
16783                               UNSPEC_FSCALE_EXP))])
16784    (set (match_operand:SF 0 "register_operand" "")
16785         (float_truncate:SF (match_dup 10)))]
16786   "TARGET_USE_FANCY_MATH_387
16787    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16788    && flag_unsafe_math_optimizations && !optimize_size"
16790   rtx temp;
16791   int i;
16793   for (i=2; i<12; i++)
16794     operands[i] = gen_reg_rtx (XFmode);
16795   temp = standard_80387_constant_rtx (5); /* fldl2e */
16796   emit_move_insn (operands[3], temp);
16797   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16800 (define_expand "expdf2"
16801   [(set (match_dup 2)
16802         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16803    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16804    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16805    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16806    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16807    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16808    (parallel [(set (match_dup 10)
16809                    (unspec:XF [(match_dup 9) (match_dup 5)]
16810                               UNSPEC_FSCALE_FRACT))
16811               (set (match_dup 11)
16812                    (unspec:XF [(match_dup 9) (match_dup 5)]
16813                               UNSPEC_FSCALE_EXP))])
16814    (set (match_operand:DF 0 "register_operand" "")
16815         (float_truncate:DF (match_dup 10)))]
16816   "TARGET_USE_FANCY_MATH_387
16817    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16818    && flag_unsafe_math_optimizations && !optimize_size"
16820   rtx temp;
16821   int i;
16823   for (i=2; i<12; i++)
16824     operands[i] = gen_reg_rtx (XFmode);
16825   temp = standard_80387_constant_rtx (5); /* fldl2e */
16826   emit_move_insn (operands[3], temp);
16827   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16830 (define_expand "expxf2"
16831   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16832                                (match_dup 2)))
16833    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16834    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16835    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16836    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16837    (parallel [(set (match_operand:XF 0 "register_operand" "")
16838                    (unspec:XF [(match_dup 8) (match_dup 4)]
16839                               UNSPEC_FSCALE_FRACT))
16840               (set (match_dup 9)
16841                    (unspec:XF [(match_dup 8) (match_dup 4)]
16842                               UNSPEC_FSCALE_EXP))])]
16843   "TARGET_USE_FANCY_MATH_387
16844    && flag_unsafe_math_optimizations && !optimize_size"
16846   rtx temp;
16847   int i;
16849   for (i=2; i<10; i++)
16850     operands[i] = gen_reg_rtx (XFmode);
16851   temp = standard_80387_constant_rtx (5); /* fldl2e */
16852   emit_move_insn (operands[2], temp);
16853   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16856 (define_expand "exp10sf2"
16857   [(set (match_dup 2)
16858         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16859    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16860    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16861    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16862    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16863    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16864    (parallel [(set (match_dup 10)
16865                    (unspec:XF [(match_dup 9) (match_dup 5)]
16866                               UNSPEC_FSCALE_FRACT))
16867               (set (match_dup 11)
16868                    (unspec:XF [(match_dup 9) (match_dup 5)]
16869                               UNSPEC_FSCALE_EXP))])
16870    (set (match_operand:SF 0 "register_operand" "")
16871         (float_truncate:SF (match_dup 10)))]
16872   "TARGET_USE_FANCY_MATH_387
16873    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16874    && flag_unsafe_math_optimizations && !optimize_size"
16876   rtx temp;
16877   int i;
16879   for (i=2; i<12; i++)
16880     operands[i] = gen_reg_rtx (XFmode);
16881   temp = standard_80387_constant_rtx (6); /* fldl2t */
16882   emit_move_insn (operands[3], temp);
16883   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16886 (define_expand "exp10df2"
16887   [(set (match_dup 2)
16888         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16889    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16890    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16891    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16892    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16893    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16894    (parallel [(set (match_dup 10)
16895                    (unspec:XF [(match_dup 9) (match_dup 5)]
16896                               UNSPEC_FSCALE_FRACT))
16897               (set (match_dup 11)
16898                    (unspec:XF [(match_dup 9) (match_dup 5)]
16899                               UNSPEC_FSCALE_EXP))])
16900    (set (match_operand:DF 0 "register_operand" "")
16901         (float_truncate:DF (match_dup 10)))]
16902   "TARGET_USE_FANCY_MATH_387
16903    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16904    && flag_unsafe_math_optimizations && !optimize_size"
16906   rtx temp;
16907   int i;
16909   for (i=2; i<12; i++)
16910     operands[i] = gen_reg_rtx (XFmode);
16911   temp = standard_80387_constant_rtx (6); /* fldl2t */
16912   emit_move_insn (operands[3], temp);
16913   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16916 (define_expand "exp10xf2"
16917   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16918                                (match_dup 2)))
16919    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16920    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16921    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16922    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16923    (parallel [(set (match_operand:XF 0 "register_operand" "")
16924                    (unspec:XF [(match_dup 8) (match_dup 4)]
16925                               UNSPEC_FSCALE_FRACT))
16926               (set (match_dup 9)
16927                    (unspec:XF [(match_dup 8) (match_dup 4)]
16928                               UNSPEC_FSCALE_EXP))])]
16929   "TARGET_USE_FANCY_MATH_387
16930    && flag_unsafe_math_optimizations && !optimize_size"
16932   rtx temp;
16933   int i;
16935   for (i=2; i<10; i++)
16936     operands[i] = gen_reg_rtx (XFmode);
16937   temp = standard_80387_constant_rtx (6); /* fldl2t */
16938   emit_move_insn (operands[2], temp);
16939   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16942 (define_expand "exp2sf2"
16943   [(set (match_dup 2)
16944         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16945    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16946    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16947    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16948    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16949    (parallel [(set (match_dup 8)
16950                    (unspec:XF [(match_dup 7) (match_dup 3)]
16951                               UNSPEC_FSCALE_FRACT))
16952               (set (match_dup 9)
16953                    (unspec:XF [(match_dup 7) (match_dup 3)]
16954                               UNSPEC_FSCALE_EXP))])
16955    (set (match_operand:SF 0 "register_operand" "")
16956         (float_truncate:SF (match_dup 8)))]
16957   "TARGET_USE_FANCY_MATH_387
16958    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16959    && flag_unsafe_math_optimizations && !optimize_size"
16961   int i;
16963   for (i=2; i<10; i++)
16964     operands[i] = gen_reg_rtx (XFmode);
16965   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16968 (define_expand "exp2df2"
16969   [(set (match_dup 2)
16970         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16971    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16972    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16973    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16974    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16975    (parallel [(set (match_dup 8)
16976                    (unspec:XF [(match_dup 7) (match_dup 3)]
16977                               UNSPEC_FSCALE_FRACT))
16978               (set (match_dup 9)
16979                    (unspec:XF [(match_dup 7) (match_dup 3)]
16980                               UNSPEC_FSCALE_EXP))])
16981    (set (match_operand:DF 0 "register_operand" "")
16982         (float_truncate:DF (match_dup 8)))]
16983   "TARGET_USE_FANCY_MATH_387
16984    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16985    && flag_unsafe_math_optimizations && !optimize_size"
16987   int i;
16989   for (i=2; i<10; i++)
16990     operands[i] = gen_reg_rtx (XFmode);
16991   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16994 (define_expand "exp2xf2"
16995   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16996    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16997    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16998    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16999    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17000    (parallel [(set (match_operand:XF 0 "register_operand" "")
17001                    (unspec:XF [(match_dup 7) (match_dup 3)]
17002                               UNSPEC_FSCALE_FRACT))
17003               (set (match_dup 8)
17004                    (unspec:XF [(match_dup 7) (match_dup 3)]
17005                               UNSPEC_FSCALE_EXP))])]
17006   "TARGET_USE_FANCY_MATH_387
17007    && flag_unsafe_math_optimizations && !optimize_size"
17009   int i;
17011   for (i=2; i<9; i++)
17012     operands[i] = gen_reg_rtx (XFmode);
17013   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17016 (define_expand "expm1df2"
17017   [(set (match_dup 2)
17018         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17019    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17020    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17021    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17022    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17023    (parallel [(set (match_dup 8)
17024                    (unspec:XF [(match_dup 7) (match_dup 5)]
17025                               UNSPEC_FSCALE_FRACT))
17026                    (set (match_dup 9)
17027                    (unspec:XF [(match_dup 7) (match_dup 5)]
17028                               UNSPEC_FSCALE_EXP))])
17029    (parallel [(set (match_dup 11)
17030                    (unspec:XF [(match_dup 10) (match_dup 9)]
17031                               UNSPEC_FSCALE_FRACT))
17032               (set (match_dup 12)
17033                    (unspec:XF [(match_dup 10) (match_dup 9)]
17034                               UNSPEC_FSCALE_EXP))])
17035    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17036    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17037    (set (match_operand:DF 0 "register_operand" "")
17038         (float_truncate:DF (match_dup 14)))]
17039   "TARGET_USE_FANCY_MATH_387
17040    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17041    && flag_unsafe_math_optimizations && !optimize_size"
17043   rtx temp;
17044   int i;
17046   for (i=2; i<15; i++)
17047     operands[i] = gen_reg_rtx (XFmode);
17048   temp = standard_80387_constant_rtx (5); /* fldl2e */
17049   emit_move_insn (operands[3], temp);
17050   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17053 (define_expand "expm1sf2"
17054   [(set (match_dup 2)
17055         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17056    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17057    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17058    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17059    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17060    (parallel [(set (match_dup 8)
17061                    (unspec:XF [(match_dup 7) (match_dup 5)]
17062                               UNSPEC_FSCALE_FRACT))
17063                    (set (match_dup 9)
17064                    (unspec:XF [(match_dup 7) (match_dup 5)]
17065                               UNSPEC_FSCALE_EXP))])
17066    (parallel [(set (match_dup 11)
17067                    (unspec:XF [(match_dup 10) (match_dup 9)]
17068                               UNSPEC_FSCALE_FRACT))
17069               (set (match_dup 12)
17070                    (unspec:XF [(match_dup 10) (match_dup 9)]
17071                               UNSPEC_FSCALE_EXP))])
17072    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17073    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17074    (set (match_operand:SF 0 "register_operand" "")
17075         (float_truncate:SF (match_dup 14)))]
17076   "TARGET_USE_FANCY_MATH_387
17077    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17078    && flag_unsafe_math_optimizations && !optimize_size"
17080   rtx temp;
17081   int i;
17083   for (i=2; i<15; i++)
17084     operands[i] = gen_reg_rtx (XFmode);
17085   temp = standard_80387_constant_rtx (5); /* fldl2e */
17086   emit_move_insn (operands[3], temp);
17087   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17090 (define_expand "expm1xf2"
17091   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17092                                (match_dup 2)))
17093    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17094    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17095    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17096    (parallel [(set (match_dup 7)
17097                    (unspec:XF [(match_dup 6) (match_dup 4)]
17098                               UNSPEC_FSCALE_FRACT))
17099                    (set (match_dup 8)
17100                    (unspec:XF [(match_dup 6) (match_dup 4)]
17101                               UNSPEC_FSCALE_EXP))])
17102    (parallel [(set (match_dup 10)
17103                    (unspec:XF [(match_dup 9) (match_dup 8)]
17104                               UNSPEC_FSCALE_FRACT))
17105               (set (match_dup 11)
17106                    (unspec:XF [(match_dup 9) (match_dup 8)]
17107                               UNSPEC_FSCALE_EXP))])
17108    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17109    (set (match_operand:XF 0 "register_operand" "")
17110         (plus:XF (match_dup 12) (match_dup 7)))]
17111   "TARGET_USE_FANCY_MATH_387
17112    && flag_unsafe_math_optimizations && !optimize_size"
17114   rtx temp;
17115   int i;
17117   for (i=2; i<13; i++)
17118     operands[i] = gen_reg_rtx (XFmode);
17119   temp = standard_80387_constant_rtx (5); /* fldl2e */
17120   emit_move_insn (operands[2], temp);
17121   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17124 (define_expand "ldexpdf3"
17125   [(set (match_dup 3)
17126         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17127    (set (match_dup 4)
17128         (float:XF (match_operand:SI 2 "register_operand" "")))
17129    (parallel [(set (match_dup 5)
17130                    (unspec:XF [(match_dup 3) (match_dup 4)]
17131                               UNSPEC_FSCALE_FRACT))
17132               (set (match_dup 6)
17133                    (unspec:XF [(match_dup 3) (match_dup 4)]
17134                               UNSPEC_FSCALE_EXP))])
17135    (set (match_operand:DF 0 "register_operand" "")
17136         (float_truncate:DF (match_dup 5)))]
17137   "TARGET_USE_FANCY_MATH_387
17138    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17139    && flag_unsafe_math_optimizations && !optimize_size"
17141   int i;
17143   for (i=3; i<7; i++)
17144     operands[i] = gen_reg_rtx (XFmode);
17147 (define_expand "ldexpsf3"
17148   [(set (match_dup 3)
17149         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17150    (set (match_dup 4)
17151         (float:XF (match_operand:SI 2 "register_operand" "")))
17152    (parallel [(set (match_dup 5)
17153                    (unspec:XF [(match_dup 3) (match_dup 4)]
17154                               UNSPEC_FSCALE_FRACT))
17155               (set (match_dup 6)
17156                    (unspec:XF [(match_dup 3) (match_dup 4)]
17157                               UNSPEC_FSCALE_EXP))])
17158    (set (match_operand:SF 0 "register_operand" "")
17159         (float_truncate:SF (match_dup 5)))]
17160   "TARGET_USE_FANCY_MATH_387
17161    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17162    && flag_unsafe_math_optimizations && !optimize_size"
17164   int i;
17166   for (i=3; i<7; i++)
17167     operands[i] = gen_reg_rtx (XFmode);
17170 (define_expand "ldexpxf3"
17171   [(set (match_dup 3)
17172         (float:XF (match_operand:SI 2 "register_operand" "")))
17173    (parallel [(set (match_operand:XF 0 " register_operand" "")
17174                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17175                                (match_dup 3)]
17176                               UNSPEC_FSCALE_FRACT))
17177               (set (match_dup 4)
17178                    (unspec:XF [(match_dup 1) (match_dup 3)]
17179                               UNSPEC_FSCALE_EXP))])]
17180   "TARGET_USE_FANCY_MATH_387
17181    && flag_unsafe_math_optimizations && !optimize_size"
17183   int i;
17185   for (i=3; i<5; i++)
17186     operands[i] = gen_reg_rtx (XFmode);
17190 (define_insn "frndintxf2"
17191   [(set (match_operand:XF 0 "register_operand" "=f")
17192         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17193          UNSPEC_FRNDINT))]
17194   "TARGET_USE_FANCY_MATH_387
17195    && flag_unsafe_math_optimizations"
17196   "frndint"
17197   [(set_attr "type" "fpspc")
17198    (set_attr "mode" "XF")])
17200 (define_expand "rintdf2"
17201   [(use (match_operand:DF 0 "register_operand" ""))
17202    (use (match_operand:DF 1 "register_operand" ""))]
17203   "(TARGET_USE_FANCY_MATH_387
17204     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17205     && flag_unsafe_math_optimizations)
17206    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17207        && !flag_trapping_math
17208        && !optimize_size)"
17210   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17211       && !flag_trapping_math
17212       && !optimize_size)
17213     ix86_expand_rint (operand0, operand1);
17214   else
17215     {
17216       rtx op0 = gen_reg_rtx (XFmode);
17217       rtx op1 = gen_reg_rtx (XFmode);
17219       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17220       emit_insn (gen_frndintxf2 (op0, op1));
17222       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17223     }
17224   DONE;
17227 (define_expand "rintsf2"
17228   [(use (match_operand:SF 0 "register_operand" ""))
17229    (use (match_operand:SF 1 "register_operand" ""))]
17230   "(TARGET_USE_FANCY_MATH_387
17231     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17232     && flag_unsafe_math_optimizations)
17233    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17234        && !flag_trapping_math
17235        && !optimize_size)"
17237   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17238       && !flag_trapping_math
17239       && !optimize_size)
17240     ix86_expand_rint (operand0, operand1);
17241   else
17242     {
17243       rtx op0 = gen_reg_rtx (XFmode);
17244       rtx op1 = gen_reg_rtx (XFmode);
17246       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17247       emit_insn (gen_frndintxf2 (op0, op1));
17249       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17250     }
17251   DONE;
17254 (define_expand "rintxf2"
17255   [(use (match_operand:XF 0 "register_operand" ""))
17256    (use (match_operand:XF 1 "register_operand" ""))]
17257   "TARGET_USE_FANCY_MATH_387
17258    && flag_unsafe_math_optimizations && !optimize_size"
17260   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17261   DONE;
17264 (define_expand "roundsf2"
17265   [(match_operand:SF 0 "register_operand" "")
17266    (match_operand:SF 1 "nonimmediate_operand" "")]
17267   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17268    && !flag_trapping_math && !flag_rounding_math
17269    && !optimize_size"
17271   ix86_expand_round (operand0, operand1);
17272   DONE;
17275 (define_expand "rounddf2"
17276   [(match_operand:DF 0 "register_operand" "")
17277    (match_operand:DF 1 "nonimmediate_operand" "")]
17278   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17279    && !flag_trapping_math && !flag_rounding_math
17280    && !optimize_size"
17282   if (TARGET_64BIT)
17283     ix86_expand_round (operand0, operand1);
17284   else
17285     ix86_expand_rounddf_32 (operand0, operand1);
17286   DONE;
17289 (define_insn_and_split "*fistdi2_1"
17290   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17291         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17292          UNSPEC_FIST))]
17293   "TARGET_USE_FANCY_MATH_387
17294    && !(reload_completed || reload_in_progress)"
17295   "#"
17296   "&& 1"
17297   [(const_int 0)]
17299   if (memory_operand (operands[0], VOIDmode))
17300     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17301   else
17302     {
17303       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17304       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17305                                          operands[2]));
17306     }
17307   DONE;
17309   [(set_attr "type" "fpspc")
17310    (set_attr "mode" "DI")])
17312 (define_insn "fistdi2"
17313   [(set (match_operand:DI 0 "memory_operand" "=m")
17314         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17315          UNSPEC_FIST))
17316    (clobber (match_scratch:XF 2 "=&1f"))]
17317   "TARGET_USE_FANCY_MATH_387"
17318   "* return output_fix_trunc (insn, operands, 0);"
17319   [(set_attr "type" "fpspc")
17320    (set_attr "mode" "DI")])
17322 (define_insn "fistdi2_with_temp"
17323   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17324         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17325          UNSPEC_FIST))
17326    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17327    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17328   "TARGET_USE_FANCY_MATH_387"
17329   "#"
17330   [(set_attr "type" "fpspc")
17331    (set_attr "mode" "DI")])
17333 (define_split
17334   [(set (match_operand:DI 0 "register_operand" "")
17335         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17336          UNSPEC_FIST))
17337    (clobber (match_operand:DI 2 "memory_operand" ""))
17338    (clobber (match_scratch 3 ""))]
17339   "reload_completed"
17340   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17341               (clobber (match_dup 3))])
17342    (set (match_dup 0) (match_dup 2))]
17343   "")
17345 (define_split
17346   [(set (match_operand:DI 0 "memory_operand" "")
17347         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17348          UNSPEC_FIST))
17349    (clobber (match_operand:DI 2 "memory_operand" ""))
17350    (clobber (match_scratch 3 ""))]
17351   "reload_completed"
17352   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17353               (clobber (match_dup 3))])]
17354   "")
17356 (define_insn_and_split "*fist<mode>2_1"
17357   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17358         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17359          UNSPEC_FIST))]
17360   "TARGET_USE_FANCY_MATH_387
17361    && !(reload_completed || reload_in_progress)"
17362   "#"
17363   "&& 1"
17364   [(const_int 0)]
17366   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17367   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17368                                         operands[2]));
17369   DONE;
17371   [(set_attr "type" "fpspc")
17372    (set_attr "mode" "<MODE>")])
17374 (define_insn "fist<mode>2"
17375   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17376         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17377          UNSPEC_FIST))]
17378   "TARGET_USE_FANCY_MATH_387"
17379   "* return output_fix_trunc (insn, operands, 0);"
17380   [(set_attr "type" "fpspc")
17381    (set_attr "mode" "<MODE>")])
17383 (define_insn "fist<mode>2_with_temp"
17384   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17385         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17386          UNSPEC_FIST))
17387    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17388   "TARGET_USE_FANCY_MATH_387"
17389   "#"
17390   [(set_attr "type" "fpspc")
17391    (set_attr "mode" "<MODE>")])
17393 (define_split
17394   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17395         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17396          UNSPEC_FIST))
17397    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17398   "reload_completed"
17399   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17400                        UNSPEC_FIST))
17401    (set (match_dup 0) (match_dup 2))]
17402   "")
17404 (define_split
17405   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17406         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17407          UNSPEC_FIST))
17408    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17409   "reload_completed"
17410   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17411                        UNSPEC_FIST))]
17412   "")
17414 (define_expand "lrintxf<mode>2"
17415   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17416      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17417       UNSPEC_FIST))]
17418   "TARGET_USE_FANCY_MATH_387"
17419   "")
17421 (define_expand "lrint<mode>di2"
17422   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17423      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17424       UNSPEC_FIX_NOTRUNC))]
17425   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17426   "")
17428 (define_expand "lrint<mode>si2"
17429   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17430      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17431       UNSPEC_FIX_NOTRUNC))]
17432   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17433   "")
17435 (define_expand "lround<mode>di2"
17436   [(match_operand:DI 0 "nonimmediate_operand" "")
17437    (match_operand:SSEMODEF 1 "register_operand" "")]
17438   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17439    && !flag_trapping_math && !flag_rounding_math
17440    && !optimize_size"
17442   ix86_expand_lround (operand0, operand1);
17443   DONE;
17446 (define_expand "lround<mode>si2"
17447   [(match_operand:SI 0 "nonimmediate_operand" "")
17448    (match_operand:SSEMODEF 1 "register_operand" "")]
17449   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17450    && !flag_trapping_math && !flag_rounding_math
17451    && !optimize_size"
17453   ix86_expand_lround (operand0, operand1);
17454   DONE;
17457 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17458 (define_insn_and_split "frndintxf2_floor"
17459   [(set (match_operand:XF 0 "register_operand" "=f")
17460         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17461          UNSPEC_FRNDINT_FLOOR))
17462    (clobber (reg:CC FLAGS_REG))]
17463   "TARGET_USE_FANCY_MATH_387
17464    && flag_unsafe_math_optimizations
17465    && !(reload_completed || reload_in_progress)"
17466   "#"
17467   "&& 1"
17468   [(const_int 0)]
17470   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17472   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17473   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17475   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17476                                         operands[2], operands[3]));
17477   DONE;
17479   [(set_attr "type" "frndint")
17480    (set_attr "i387_cw" "floor")
17481    (set_attr "mode" "XF")])
17483 (define_insn "frndintxf2_floor_i387"
17484   [(set (match_operand:XF 0 "register_operand" "=f")
17485         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17486          UNSPEC_FRNDINT_FLOOR))
17487    (use (match_operand:HI 2 "memory_operand" "m"))
17488    (use (match_operand:HI 3 "memory_operand" "m"))]
17489   "TARGET_USE_FANCY_MATH_387
17490    && flag_unsafe_math_optimizations"
17491   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17492   [(set_attr "type" "frndint")
17493    (set_attr "i387_cw" "floor")
17494    (set_attr "mode" "XF")])
17496 (define_expand "floorxf2"
17497   [(use (match_operand:XF 0 "register_operand" ""))
17498    (use (match_operand:XF 1 "register_operand" ""))]
17499   "TARGET_USE_FANCY_MATH_387
17500    && flag_unsafe_math_optimizations && !optimize_size"
17502   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17503   DONE;
17506 (define_expand "floordf2"
17507   [(use (match_operand:DF 0 "register_operand" ""))
17508    (use (match_operand:DF 1 "register_operand" ""))]
17509   "((TARGET_USE_FANCY_MATH_387
17510      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17511      && flag_unsafe_math_optimizations)
17512     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17513         && !flag_trapping_math))
17514    && !optimize_size"
17516   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17517       && !flag_trapping_math)
17518     {
17519       if (TARGET_64BIT)
17520         ix86_expand_floorceil (operand0, operand1, true);
17521       else
17522         ix86_expand_floorceildf_32 (operand0, operand1, true);
17523     }
17524   else
17525     {
17526       rtx op0 = gen_reg_rtx (XFmode);
17527       rtx op1 = gen_reg_rtx (XFmode);
17529       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17530       emit_insn (gen_frndintxf2_floor (op0, op1));
17532       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17533     }
17534   DONE;
17537 (define_expand "floorsf2"
17538   [(use (match_operand:SF 0 "register_operand" ""))
17539    (use (match_operand:SF 1 "register_operand" ""))]
17540   "((TARGET_USE_FANCY_MATH_387
17541      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17542      && flag_unsafe_math_optimizations)
17543     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17544         && !flag_trapping_math))
17545    && !optimize_size"
17547   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17548       && !flag_trapping_math)
17549     ix86_expand_floorceil (operand0, operand1, true);
17550   else
17551     {
17552       rtx op0 = gen_reg_rtx (XFmode);
17553       rtx op1 = gen_reg_rtx (XFmode);
17555       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17556       emit_insn (gen_frndintxf2_floor (op0, op1));
17558       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17559     }
17560   DONE;
17563 (define_insn_and_split "*fist<mode>2_floor_1"
17564   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17565         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17566          UNSPEC_FIST_FLOOR))
17567    (clobber (reg:CC FLAGS_REG))]
17568   "TARGET_USE_FANCY_MATH_387
17569    && flag_unsafe_math_optimizations
17570    && !(reload_completed || reload_in_progress)"
17571   "#"
17572   "&& 1"
17573   [(const_int 0)]
17575   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17577   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17578   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17579   if (memory_operand (operands[0], VOIDmode))
17580     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17581                                       operands[2], operands[3]));
17582   else
17583     {
17584       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17585       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17586                                                   operands[2], operands[3],
17587                                                   operands[4]));
17588     }
17589   DONE;
17591   [(set_attr "type" "fistp")
17592    (set_attr "i387_cw" "floor")
17593    (set_attr "mode" "<MODE>")])
17595 (define_insn "fistdi2_floor"
17596   [(set (match_operand:DI 0 "memory_operand" "=m")
17597         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17598          UNSPEC_FIST_FLOOR))
17599    (use (match_operand:HI 2 "memory_operand" "m"))
17600    (use (match_operand:HI 3 "memory_operand" "m"))
17601    (clobber (match_scratch:XF 4 "=&1f"))]
17602   "TARGET_USE_FANCY_MATH_387
17603    && flag_unsafe_math_optimizations"
17604   "* return output_fix_trunc (insn, operands, 0);"
17605   [(set_attr "type" "fistp")
17606    (set_attr "i387_cw" "floor")
17607    (set_attr "mode" "DI")])
17609 (define_insn "fistdi2_floor_with_temp"
17610   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17611         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17612          UNSPEC_FIST_FLOOR))
17613    (use (match_operand:HI 2 "memory_operand" "m,m"))
17614    (use (match_operand:HI 3 "memory_operand" "m,m"))
17615    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17616    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17617   "TARGET_USE_FANCY_MATH_387
17618    && flag_unsafe_math_optimizations"
17619   "#"
17620   [(set_attr "type" "fistp")
17621    (set_attr "i387_cw" "floor")
17622    (set_attr "mode" "DI")])
17624 (define_split
17625   [(set (match_operand:DI 0 "register_operand" "")
17626         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17627          UNSPEC_FIST_FLOOR))
17628    (use (match_operand:HI 2 "memory_operand" ""))
17629    (use (match_operand:HI 3 "memory_operand" ""))
17630    (clobber (match_operand:DI 4 "memory_operand" ""))
17631    (clobber (match_scratch 5 ""))]
17632   "reload_completed"
17633   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17634               (use (match_dup 2))
17635               (use (match_dup 3))
17636               (clobber (match_dup 5))])
17637    (set (match_dup 0) (match_dup 4))]
17638   "")
17640 (define_split
17641   [(set (match_operand:DI 0 "memory_operand" "")
17642         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17643          UNSPEC_FIST_FLOOR))
17644    (use (match_operand:HI 2 "memory_operand" ""))
17645    (use (match_operand:HI 3 "memory_operand" ""))
17646    (clobber (match_operand:DI 4 "memory_operand" ""))
17647    (clobber (match_scratch 5 ""))]
17648   "reload_completed"
17649   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17650               (use (match_dup 2))
17651               (use (match_dup 3))
17652               (clobber (match_dup 5))])]
17653   "")
17655 (define_insn "fist<mode>2_floor"
17656   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17657         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17658          UNSPEC_FIST_FLOOR))
17659    (use (match_operand:HI 2 "memory_operand" "m"))
17660    (use (match_operand:HI 3 "memory_operand" "m"))]
17661   "TARGET_USE_FANCY_MATH_387
17662    && flag_unsafe_math_optimizations"
17663   "* return output_fix_trunc (insn, operands, 0);"
17664   [(set_attr "type" "fistp")
17665    (set_attr "i387_cw" "floor")
17666    (set_attr "mode" "<MODE>")])
17668 (define_insn "fist<mode>2_floor_with_temp"
17669   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17670         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17671          UNSPEC_FIST_FLOOR))
17672    (use (match_operand:HI 2 "memory_operand" "m,m"))
17673    (use (match_operand:HI 3 "memory_operand" "m,m"))
17674    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17675   "TARGET_USE_FANCY_MATH_387
17676    && flag_unsafe_math_optimizations"
17677   "#"
17678   [(set_attr "type" "fistp")
17679    (set_attr "i387_cw" "floor")
17680    (set_attr "mode" "<MODE>")])
17682 (define_split
17683   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17684         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17685          UNSPEC_FIST_FLOOR))
17686    (use (match_operand:HI 2 "memory_operand" ""))
17687    (use (match_operand:HI 3 "memory_operand" ""))
17688    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17689   "reload_completed"
17690   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17691                                   UNSPEC_FIST_FLOOR))
17692               (use (match_dup 2))
17693               (use (match_dup 3))])
17694    (set (match_dup 0) (match_dup 4))]
17695   "")
17697 (define_split
17698   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17699         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17700          UNSPEC_FIST_FLOOR))
17701    (use (match_operand:HI 2 "memory_operand" ""))
17702    (use (match_operand:HI 3 "memory_operand" ""))
17703    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17704   "reload_completed"
17705   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17706                                   UNSPEC_FIST_FLOOR))
17707               (use (match_dup 2))
17708               (use (match_dup 3))])]
17709   "")
17711 (define_expand "lfloorxf<mode>2"
17712   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17713                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17714                     UNSPEC_FIST_FLOOR))
17715               (clobber (reg:CC FLAGS_REG))])]
17716   "TARGET_USE_FANCY_MATH_387
17717    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17718    && flag_unsafe_math_optimizations"
17719   "")
17721 (define_expand "lfloor<mode>di2"
17722   [(match_operand:DI 0 "nonimmediate_operand" "")
17723    (match_operand:SSEMODEF 1 "register_operand" "")]
17724   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17725    && !flag_trapping_math
17726    && !optimize_size"
17728   ix86_expand_lfloorceil (operand0, operand1, true);
17729   DONE;
17732 (define_expand "lfloor<mode>si2"
17733   [(match_operand:SI 0 "nonimmediate_operand" "")
17734    (match_operand:SSEMODEF 1 "register_operand" "")]
17735   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17736    && !flag_trapping_math
17737    && (!optimize_size || !TARGET_64BIT)"
17739   ix86_expand_lfloorceil (operand0, operand1, true);
17740   DONE;
17743 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17744 (define_insn_and_split "frndintxf2_ceil"
17745   [(set (match_operand:XF 0 "register_operand" "=f")
17746         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17747          UNSPEC_FRNDINT_CEIL))
17748    (clobber (reg:CC FLAGS_REG))]
17749   "TARGET_USE_FANCY_MATH_387
17750    && flag_unsafe_math_optimizations
17751    && !(reload_completed || reload_in_progress)"
17752   "#"
17753   "&& 1"
17754   [(const_int 0)]
17756   ix86_optimize_mode_switching[I387_CEIL] = 1;
17758   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17759   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17761   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17762                                        operands[2], operands[3]));
17763   DONE;
17765   [(set_attr "type" "frndint")
17766    (set_attr "i387_cw" "ceil")
17767    (set_attr "mode" "XF")])
17769 (define_insn "frndintxf2_ceil_i387"
17770   [(set (match_operand:XF 0 "register_operand" "=f")
17771         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17772          UNSPEC_FRNDINT_CEIL))
17773    (use (match_operand:HI 2 "memory_operand" "m"))
17774    (use (match_operand:HI 3 "memory_operand" "m"))]
17775   "TARGET_USE_FANCY_MATH_387
17776    && flag_unsafe_math_optimizations"
17777   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17778   [(set_attr "type" "frndint")
17779    (set_attr "i387_cw" "ceil")
17780    (set_attr "mode" "XF")])
17782 (define_expand "ceilxf2"
17783   [(use (match_operand:XF 0 "register_operand" ""))
17784    (use (match_operand:XF 1 "register_operand" ""))]
17785   "TARGET_USE_FANCY_MATH_387
17786    && flag_unsafe_math_optimizations && !optimize_size"
17788   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17789   DONE;
17792 (define_expand "ceildf2"
17793   [(use (match_operand:DF 0 "register_operand" ""))
17794    (use (match_operand:DF 1 "register_operand" ""))]
17795   "((TARGET_USE_FANCY_MATH_387
17796      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17797      && flag_unsafe_math_optimizations)
17798     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17799         && !flag_trapping_math))
17800    && !optimize_size"
17802   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17803       && !flag_trapping_math)
17804     {
17805       if (TARGET_64BIT)
17806         ix86_expand_floorceil (operand0, operand1, false);
17807       else
17808         ix86_expand_floorceildf_32 (operand0, operand1, false);
17809     }
17810   else
17811     {
17812       rtx op0 = gen_reg_rtx (XFmode);
17813       rtx op1 = gen_reg_rtx (XFmode);
17815       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17816       emit_insn (gen_frndintxf2_ceil (op0, op1));
17818       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17819     }
17820   DONE;
17823 (define_expand "ceilsf2"
17824   [(use (match_operand:SF 0 "register_operand" ""))
17825    (use (match_operand:SF 1 "register_operand" ""))]
17826   "((TARGET_USE_FANCY_MATH_387
17827      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17828      && flag_unsafe_math_optimizations)
17829     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17830         && !flag_trapping_math))
17831    && !optimize_size"
17833   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17834       && !flag_trapping_math)
17835     ix86_expand_floorceil (operand0, operand1, false);
17836   else
17837     {
17838       rtx op0 = gen_reg_rtx (XFmode);
17839       rtx op1 = gen_reg_rtx (XFmode);
17841       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17842       emit_insn (gen_frndintxf2_ceil (op0, op1));
17844       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17845     }
17846   DONE;
17849 (define_insn_and_split "*fist<mode>2_ceil_1"
17850   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17851         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17852          UNSPEC_FIST_CEIL))
17853    (clobber (reg:CC FLAGS_REG))]
17854   "TARGET_USE_FANCY_MATH_387
17855    && flag_unsafe_math_optimizations
17856    && !(reload_completed || reload_in_progress)"
17857   "#"
17858   "&& 1"
17859   [(const_int 0)]
17861   ix86_optimize_mode_switching[I387_CEIL] = 1;
17863   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17864   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17865   if (memory_operand (operands[0], VOIDmode))
17866     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17867                                      operands[2], operands[3]));
17868   else
17869     {
17870       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17871       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17872                                                  operands[2], operands[3],
17873                                                  operands[4]));
17874     }
17875   DONE;
17877   [(set_attr "type" "fistp")
17878    (set_attr "i387_cw" "ceil")
17879    (set_attr "mode" "<MODE>")])
17881 (define_insn "fistdi2_ceil"
17882   [(set (match_operand:DI 0 "memory_operand" "=m")
17883         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17884          UNSPEC_FIST_CEIL))
17885    (use (match_operand:HI 2 "memory_operand" "m"))
17886    (use (match_operand:HI 3 "memory_operand" "m"))
17887    (clobber (match_scratch:XF 4 "=&1f"))]
17888   "TARGET_USE_FANCY_MATH_387
17889    && flag_unsafe_math_optimizations"
17890   "* return output_fix_trunc (insn, operands, 0);"
17891   [(set_attr "type" "fistp")
17892    (set_attr "i387_cw" "ceil")
17893    (set_attr "mode" "DI")])
17895 (define_insn "fistdi2_ceil_with_temp"
17896   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17897         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17898          UNSPEC_FIST_CEIL))
17899    (use (match_operand:HI 2 "memory_operand" "m,m"))
17900    (use (match_operand:HI 3 "memory_operand" "m,m"))
17901    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17902    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17903   "TARGET_USE_FANCY_MATH_387
17904    && flag_unsafe_math_optimizations"
17905   "#"
17906   [(set_attr "type" "fistp")
17907    (set_attr "i387_cw" "ceil")
17908    (set_attr "mode" "DI")])
17910 (define_split
17911   [(set (match_operand:DI 0 "register_operand" "")
17912         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17913          UNSPEC_FIST_CEIL))
17914    (use (match_operand:HI 2 "memory_operand" ""))
17915    (use (match_operand:HI 3 "memory_operand" ""))
17916    (clobber (match_operand:DI 4 "memory_operand" ""))
17917    (clobber (match_scratch 5 ""))]
17918   "reload_completed"
17919   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17920               (use (match_dup 2))
17921               (use (match_dup 3))
17922               (clobber (match_dup 5))])
17923    (set (match_dup 0) (match_dup 4))]
17924   "")
17926 (define_split
17927   [(set (match_operand:DI 0 "memory_operand" "")
17928         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17929          UNSPEC_FIST_CEIL))
17930    (use (match_operand:HI 2 "memory_operand" ""))
17931    (use (match_operand:HI 3 "memory_operand" ""))
17932    (clobber (match_operand:DI 4 "memory_operand" ""))
17933    (clobber (match_scratch 5 ""))]
17934   "reload_completed"
17935   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17936               (use (match_dup 2))
17937               (use (match_dup 3))
17938               (clobber (match_dup 5))])]
17939   "")
17941 (define_insn "fist<mode>2_ceil"
17942   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17943         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17944          UNSPEC_FIST_CEIL))
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   "* return output_fix_trunc (insn, operands, 0);"
17950   [(set_attr "type" "fistp")
17951    (set_attr "i387_cw" "ceil")
17952    (set_attr "mode" "<MODE>")])
17954 (define_insn "fist<mode>2_ceil_with_temp"
17955   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17956         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17957          UNSPEC_FIST_CEIL))
17958    (use (match_operand:HI 2 "memory_operand" "m,m"))
17959    (use (match_operand:HI 3 "memory_operand" "m,m"))
17960    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17961   "TARGET_USE_FANCY_MATH_387
17962    && flag_unsafe_math_optimizations"
17963   "#"
17964   [(set_attr "type" "fistp")
17965    (set_attr "i387_cw" "ceil")
17966    (set_attr "mode" "<MODE>")])
17968 (define_split
17969   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17970         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17971          UNSPEC_FIST_CEIL))
17972    (use (match_operand:HI 2 "memory_operand" ""))
17973    (use (match_operand:HI 3 "memory_operand" ""))
17974    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17975   "reload_completed"
17976   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17977                                   UNSPEC_FIST_CEIL))
17978               (use (match_dup 2))
17979               (use (match_dup 3))])
17980    (set (match_dup 0) (match_dup 4))]
17981   "")
17983 (define_split
17984   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17985         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17986          UNSPEC_FIST_CEIL))
17987    (use (match_operand:HI 2 "memory_operand" ""))
17988    (use (match_operand:HI 3 "memory_operand" ""))
17989    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17990   "reload_completed"
17991   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17992                                   UNSPEC_FIST_CEIL))
17993               (use (match_dup 2))
17994               (use (match_dup 3))])]
17995   "")
17997 (define_expand "lceilxf<mode>2"
17998   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17999                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18000                     UNSPEC_FIST_CEIL))
18001               (clobber (reg:CC FLAGS_REG))])]
18002   "TARGET_USE_FANCY_MATH_387
18003    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18004    && flag_unsafe_math_optimizations"
18005   "")
18007 (define_expand "lceil<mode>di2"
18008   [(match_operand:DI 0 "nonimmediate_operand" "")
18009    (match_operand:SSEMODEF 1 "register_operand" "")]
18010   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18011    && !flag_trapping_math"
18013   ix86_expand_lfloorceil (operand0, operand1, false);
18014   DONE;
18017 (define_expand "lceil<mode>si2"
18018   [(match_operand:SI 0 "nonimmediate_operand" "")
18019    (match_operand:SSEMODEF 1 "register_operand" "")]
18020   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18021    && !flag_trapping_math"
18023   ix86_expand_lfloorceil (operand0, operand1, false);
18024   DONE;
18027 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18028 (define_insn_and_split "frndintxf2_trunc"
18029   [(set (match_operand:XF 0 "register_operand" "=f")
18030         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18031          UNSPEC_FRNDINT_TRUNC))
18032    (clobber (reg:CC FLAGS_REG))]
18033   "TARGET_USE_FANCY_MATH_387
18034    && flag_unsafe_math_optimizations
18035    && !(reload_completed || reload_in_progress)"
18036   "#"
18037   "&& 1"
18038   [(const_int 0)]
18040   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18042   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18043   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18045   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18046                                         operands[2], operands[3]));
18047   DONE;
18049   [(set_attr "type" "frndint")
18050    (set_attr "i387_cw" "trunc")
18051    (set_attr "mode" "XF")])
18053 (define_insn "frndintxf2_trunc_i387"
18054   [(set (match_operand:XF 0 "register_operand" "=f")
18055         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18056          UNSPEC_FRNDINT_TRUNC))
18057    (use (match_operand:HI 2 "memory_operand" "m"))
18058    (use (match_operand:HI 3 "memory_operand" "m"))]
18059   "TARGET_USE_FANCY_MATH_387
18060    && flag_unsafe_math_optimizations"
18061   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18062   [(set_attr "type" "frndint")
18063    (set_attr "i387_cw" "trunc")
18064    (set_attr "mode" "XF")])
18066 (define_expand "btruncxf2"
18067   [(use (match_operand:XF 0 "register_operand" ""))
18068    (use (match_operand:XF 1 "register_operand" ""))]
18069   "TARGET_USE_FANCY_MATH_387
18070    && flag_unsafe_math_optimizations && !optimize_size"
18072   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18073   DONE;
18076 (define_expand "btruncdf2"
18077   [(use (match_operand:DF 0 "register_operand" ""))
18078    (use (match_operand:DF 1 "register_operand" ""))]
18079   "((TARGET_USE_FANCY_MATH_387
18080      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18081      && flag_unsafe_math_optimizations)
18082     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18083         && !flag_trapping_math))
18084    && !optimize_size"
18086   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18087       && !flag_trapping_math)
18088     {
18089       if (TARGET_64BIT)
18090         ix86_expand_trunc (operand0, operand1);
18091       else
18092         ix86_expand_truncdf_32 (operand0, operand1);
18093     }
18094   else
18095     {
18096       rtx op0 = gen_reg_rtx (XFmode);
18097       rtx op1 = gen_reg_rtx (XFmode);
18099       emit_insn (gen_extenddfxf2 (op1, operands[1]));
18100       emit_insn (gen_frndintxf2_trunc (op0, op1));
18102       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18103     }
18104   DONE;
18107 (define_expand "btruncsf2"
18108   [(use (match_operand:SF 0 "register_operand" ""))
18109    (use (match_operand:SF 1 "register_operand" ""))]
18110   "((TARGET_USE_FANCY_MATH_387
18111      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18112      && flag_unsafe_math_optimizations)
18113     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18114         && !flag_trapping_math))
18115    && !optimize_size"
18117   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18118       && !flag_trapping_math)
18119     ix86_expand_trunc (operand0, operand1);
18120   else
18121     {
18122       rtx op0 = gen_reg_rtx (XFmode);
18123       rtx op1 = gen_reg_rtx (XFmode);
18125       emit_insn (gen_extendsfxf2 (op1, operands[1]));
18126       emit_insn (gen_frndintxf2_trunc (op0, op1));
18128       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18129     }
18130   DONE;
18133 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18134 (define_insn_and_split "frndintxf2_mask_pm"
18135   [(set (match_operand:XF 0 "register_operand" "=f")
18136         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18137          UNSPEC_FRNDINT_MASK_PM))
18138    (clobber (reg:CC FLAGS_REG))]
18139   "TARGET_USE_FANCY_MATH_387
18140    && flag_unsafe_math_optimizations
18141    && !(reload_completed || reload_in_progress)"
18142   "#"
18143   "&& 1"
18144   [(const_int 0)]
18146   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18148   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18149   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18151   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18152                                           operands[2], operands[3]));
18153   DONE;
18155   [(set_attr "type" "frndint")
18156    (set_attr "i387_cw" "mask_pm")
18157    (set_attr "mode" "XF")])
18159 (define_insn "frndintxf2_mask_pm_i387"
18160   [(set (match_operand:XF 0 "register_operand" "=f")
18161         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18162          UNSPEC_FRNDINT_MASK_PM))
18163    (use (match_operand:HI 2 "memory_operand" "m"))
18164    (use (match_operand:HI 3 "memory_operand" "m"))]
18165   "TARGET_USE_FANCY_MATH_387
18166    && flag_unsafe_math_optimizations"
18167   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18168   [(set_attr "type" "frndint")
18169    (set_attr "i387_cw" "mask_pm")
18170    (set_attr "mode" "XF")])
18172 (define_expand "nearbyintxf2"
18173   [(use (match_operand:XF 0 "register_operand" ""))
18174    (use (match_operand:XF 1 "register_operand" ""))]
18175   "TARGET_USE_FANCY_MATH_387
18176    && flag_unsafe_math_optimizations"
18178   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18180   DONE;
18183 (define_expand "nearbyintdf2"
18184   [(use (match_operand:DF 0 "register_operand" ""))
18185    (use (match_operand:DF 1 "register_operand" ""))]
18186   "TARGET_USE_FANCY_MATH_387
18187    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18188    && flag_unsafe_math_optimizations"
18190   rtx op0 = gen_reg_rtx (XFmode);
18191   rtx op1 = gen_reg_rtx (XFmode);
18193   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18194   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18196   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18197   DONE;
18200 (define_expand "nearbyintsf2"
18201   [(use (match_operand:SF 0 "register_operand" ""))
18202    (use (match_operand:SF 1 "register_operand" ""))]
18203   "TARGET_USE_FANCY_MATH_387
18204    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18205    && flag_unsafe_math_optimizations"
18207   rtx op0 = gen_reg_rtx (XFmode);
18208   rtx op1 = gen_reg_rtx (XFmode);
18210   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18211   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18213   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18214   DONE;
18218 ;; Block operation instructions
18220 (define_insn "cld"
18221  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18222  ""
18223  "cld"
18224   [(set_attr "type" "cld")])
18226 (define_expand "movmemsi"
18227   [(use (match_operand:BLK 0 "memory_operand" ""))
18228    (use (match_operand:BLK 1 "memory_operand" ""))
18229    (use (match_operand:SI 2 "nonmemory_operand" ""))
18230    (use (match_operand:SI 3 "const_int_operand" ""))]
18231   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18233  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18234    DONE;
18235  else
18236    FAIL;
18239 (define_expand "movmemdi"
18240   [(use (match_operand:BLK 0 "memory_operand" ""))
18241    (use (match_operand:BLK 1 "memory_operand" ""))
18242    (use (match_operand:DI 2 "nonmemory_operand" ""))
18243    (use (match_operand:DI 3 "const_int_operand" ""))]
18244   "TARGET_64BIT"
18246  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18247    DONE;
18248  else
18249    FAIL;
18252 ;; Most CPUs don't like single string operations
18253 ;; Handle this case here to simplify previous expander.
18255 (define_expand "strmov"
18256   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18257    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18258    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18259               (clobber (reg:CC FLAGS_REG))])
18260    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18261               (clobber (reg:CC FLAGS_REG))])]
18262   ""
18264   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18266   /* If .md ever supports :P for Pmode, these can be directly
18267      in the pattern above.  */
18268   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18269   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18271   if (TARGET_SINGLE_STRINGOP || optimize_size)
18272     {
18273       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18274                                       operands[2], operands[3],
18275                                       operands[5], operands[6]));
18276       DONE;
18277     }
18279   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18282 (define_expand "strmov_singleop"
18283   [(parallel [(set (match_operand 1 "memory_operand" "")
18284                    (match_operand 3 "memory_operand" ""))
18285               (set (match_operand 0 "register_operand" "")
18286                    (match_operand 4 "" ""))
18287               (set (match_operand 2 "register_operand" "")
18288                    (match_operand 5 "" ""))
18289               (use (reg:SI DIRFLAG_REG))])]
18290   "TARGET_SINGLE_STRINGOP || optimize_size"
18291   "")
18293 (define_insn "*strmovdi_rex_1"
18294   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18295         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18296    (set (match_operand:DI 0 "register_operand" "=D")
18297         (plus:DI (match_dup 2)
18298                  (const_int 8)))
18299    (set (match_operand:DI 1 "register_operand" "=S")
18300         (plus:DI (match_dup 3)
18301                  (const_int 8)))
18302    (use (reg:SI DIRFLAG_REG))]
18303   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18304   "movsq"
18305   [(set_attr "type" "str")
18306    (set_attr "mode" "DI")
18307    (set_attr "memory" "both")])
18309 (define_insn "*strmovsi_1"
18310   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18311         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18312    (set (match_operand:SI 0 "register_operand" "=D")
18313         (plus:SI (match_dup 2)
18314                  (const_int 4)))
18315    (set (match_operand:SI 1 "register_operand" "=S")
18316         (plus:SI (match_dup 3)
18317                  (const_int 4)))
18318    (use (reg:SI DIRFLAG_REG))]
18319   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18320   "{movsl|movsd}"
18321   [(set_attr "type" "str")
18322    (set_attr "mode" "SI")
18323    (set_attr "memory" "both")])
18325 (define_insn "*strmovsi_rex_1"
18326   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18327         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18328    (set (match_operand:DI 0 "register_operand" "=D")
18329         (plus:DI (match_dup 2)
18330                  (const_int 4)))
18331    (set (match_operand:DI 1 "register_operand" "=S")
18332         (plus:DI (match_dup 3)
18333                  (const_int 4)))
18334    (use (reg:SI DIRFLAG_REG))]
18335   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18336   "{movsl|movsd}"
18337   [(set_attr "type" "str")
18338    (set_attr "mode" "SI")
18339    (set_attr "memory" "both")])
18341 (define_insn "*strmovhi_1"
18342   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18343         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18344    (set (match_operand:SI 0 "register_operand" "=D")
18345         (plus:SI (match_dup 2)
18346                  (const_int 2)))
18347    (set (match_operand:SI 1 "register_operand" "=S")
18348         (plus:SI (match_dup 3)
18349                  (const_int 2)))
18350    (use (reg:SI DIRFLAG_REG))]
18351   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18352   "movsw"
18353   [(set_attr "type" "str")
18354    (set_attr "memory" "both")
18355    (set_attr "mode" "HI")])
18357 (define_insn "*strmovhi_rex_1"
18358   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18359         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18360    (set (match_operand:DI 0 "register_operand" "=D")
18361         (plus:DI (match_dup 2)
18362                  (const_int 2)))
18363    (set (match_operand:DI 1 "register_operand" "=S")
18364         (plus:DI (match_dup 3)
18365                  (const_int 2)))
18366    (use (reg:SI DIRFLAG_REG))]
18367   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18368   "movsw"
18369   [(set_attr "type" "str")
18370    (set_attr "memory" "both")
18371    (set_attr "mode" "HI")])
18373 (define_insn "*strmovqi_1"
18374   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18375         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18376    (set (match_operand:SI 0 "register_operand" "=D")
18377         (plus:SI (match_dup 2)
18378                  (const_int 1)))
18379    (set (match_operand:SI 1 "register_operand" "=S")
18380         (plus:SI (match_dup 3)
18381                  (const_int 1)))
18382    (use (reg:SI DIRFLAG_REG))]
18383   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18384   "movsb"
18385   [(set_attr "type" "str")
18386    (set_attr "memory" "both")
18387    (set_attr "mode" "QI")])
18389 (define_insn "*strmovqi_rex_1"
18390   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18391         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18392    (set (match_operand:DI 0 "register_operand" "=D")
18393         (plus:DI (match_dup 2)
18394                  (const_int 1)))
18395    (set (match_operand:DI 1 "register_operand" "=S")
18396         (plus:DI (match_dup 3)
18397                  (const_int 1)))
18398    (use (reg:SI DIRFLAG_REG))]
18399   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18400   "movsb"
18401   [(set_attr "type" "str")
18402    (set_attr "memory" "both")
18403    (set_attr "mode" "QI")])
18405 (define_expand "rep_mov"
18406   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18407               (set (match_operand 0 "register_operand" "")
18408                    (match_operand 5 "" ""))
18409               (set (match_operand 2 "register_operand" "")
18410                    (match_operand 6 "" ""))
18411               (set (match_operand 1 "memory_operand" "")
18412                    (match_operand 3 "memory_operand" ""))
18413               (use (match_dup 4))
18414               (use (reg:SI DIRFLAG_REG))])]
18415   ""
18416   "")
18418 (define_insn "*rep_movdi_rex64"
18419   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18420    (set (match_operand:DI 0 "register_operand" "=D")
18421         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18422                             (const_int 3))
18423                  (match_operand:DI 3 "register_operand" "0")))
18424    (set (match_operand:DI 1 "register_operand" "=S")
18425         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18426                  (match_operand:DI 4 "register_operand" "1")))
18427    (set (mem:BLK (match_dup 3))
18428         (mem:BLK (match_dup 4)))
18429    (use (match_dup 5))
18430    (use (reg:SI DIRFLAG_REG))]
18431   "TARGET_64BIT"
18432   "{rep\;movsq|rep movsq}"
18433   [(set_attr "type" "str")
18434    (set_attr "prefix_rep" "1")
18435    (set_attr "memory" "both")
18436    (set_attr "mode" "DI")])
18438 (define_insn "*rep_movsi"
18439   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18440    (set (match_operand:SI 0 "register_operand" "=D")
18441         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18442                             (const_int 2))
18443                  (match_operand:SI 3 "register_operand" "0")))
18444    (set (match_operand:SI 1 "register_operand" "=S")
18445         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18446                  (match_operand:SI 4 "register_operand" "1")))
18447    (set (mem:BLK (match_dup 3))
18448         (mem:BLK (match_dup 4)))
18449    (use (match_dup 5))
18450    (use (reg:SI DIRFLAG_REG))]
18451   "!TARGET_64BIT"
18452   "{rep\;movsl|rep movsd}"
18453   [(set_attr "type" "str")
18454    (set_attr "prefix_rep" "1")
18455    (set_attr "memory" "both")
18456    (set_attr "mode" "SI")])
18458 (define_insn "*rep_movsi_rex64"
18459   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18460    (set (match_operand:DI 0 "register_operand" "=D")
18461         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18462                             (const_int 2))
18463                  (match_operand:DI 3 "register_operand" "0")))
18464    (set (match_operand:DI 1 "register_operand" "=S")
18465         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18466                  (match_operand:DI 4 "register_operand" "1")))
18467    (set (mem:BLK (match_dup 3))
18468         (mem:BLK (match_dup 4)))
18469    (use (match_dup 5))
18470    (use (reg:SI DIRFLAG_REG))]
18471   "TARGET_64BIT"
18472   "{rep\;movsl|rep movsd}"
18473   [(set_attr "type" "str")
18474    (set_attr "prefix_rep" "1")
18475    (set_attr "memory" "both")
18476    (set_attr "mode" "SI")])
18478 (define_insn "*rep_movqi"
18479   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18480    (set (match_operand:SI 0 "register_operand" "=D")
18481         (plus:SI (match_operand:SI 3 "register_operand" "0")
18482                  (match_operand:SI 5 "register_operand" "2")))
18483    (set (match_operand:SI 1 "register_operand" "=S")
18484         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18485    (set (mem:BLK (match_dup 3))
18486         (mem:BLK (match_dup 4)))
18487    (use (match_dup 5))
18488    (use (reg:SI DIRFLAG_REG))]
18489   "!TARGET_64BIT"
18490   "{rep\;movsb|rep movsb}"
18491   [(set_attr "type" "str")
18492    (set_attr "prefix_rep" "1")
18493    (set_attr "memory" "both")
18494    (set_attr "mode" "SI")])
18496 (define_insn "*rep_movqi_rex64"
18497   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18498    (set (match_operand:DI 0 "register_operand" "=D")
18499         (plus:DI (match_operand:DI 3 "register_operand" "0")
18500                  (match_operand:DI 5 "register_operand" "2")))
18501    (set (match_operand:DI 1 "register_operand" "=S")
18502         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18503    (set (mem:BLK (match_dup 3))
18504         (mem:BLK (match_dup 4)))
18505    (use (match_dup 5))
18506    (use (reg:SI DIRFLAG_REG))]
18507   "TARGET_64BIT"
18508   "{rep\;movsb|rep movsb}"
18509   [(set_attr "type" "str")
18510    (set_attr "prefix_rep" "1")
18511    (set_attr "memory" "both")
18512    (set_attr "mode" "SI")])
18514 (define_expand "setmemsi"
18515    [(use (match_operand:BLK 0 "memory_operand" ""))
18516     (use (match_operand:SI 1 "nonmemory_operand" ""))
18517     (use (match_operand 2 "const_int_operand" ""))
18518     (use (match_operand 3 "const_int_operand" ""))]
18519   ""
18521  /* If value to set is not zero, use the library routine.  */
18522  if (operands[2] != const0_rtx)
18523    FAIL;
18525  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18526    DONE;
18527  else
18528    FAIL;
18531 (define_expand "setmemdi"
18532    [(use (match_operand:BLK 0 "memory_operand" ""))
18533     (use (match_operand:DI 1 "nonmemory_operand" ""))
18534     (use (match_operand 2 "const_int_operand" ""))
18535     (use (match_operand 3 "const_int_operand" ""))]
18536   "TARGET_64BIT"
18538  /* If value to set is not zero, use the library routine.  */
18539  if (operands[2] != const0_rtx)
18540    FAIL;
18542  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18543    DONE;
18544  else
18545    FAIL;
18548 ;; Most CPUs don't like single string operations
18549 ;; Handle this case here to simplify previous expander.
18551 (define_expand "strset"
18552   [(set (match_operand 1 "memory_operand" "")
18553         (match_operand 2 "register_operand" ""))
18554    (parallel [(set (match_operand 0 "register_operand" "")
18555                    (match_dup 3))
18556               (clobber (reg:CC FLAGS_REG))])]
18557   ""
18559   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18560     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18562   /* If .md ever supports :P for Pmode, this can be directly
18563      in the pattern above.  */
18564   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18565                               GEN_INT (GET_MODE_SIZE (GET_MODE
18566                                                       (operands[2]))));
18567   if (TARGET_SINGLE_STRINGOP || optimize_size)
18568     {
18569       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18570                                       operands[3]));
18571       DONE;
18572     }
18575 (define_expand "strset_singleop"
18576   [(parallel [(set (match_operand 1 "memory_operand" "")
18577                    (match_operand 2 "register_operand" ""))
18578               (set (match_operand 0 "register_operand" "")
18579                    (match_operand 3 "" ""))
18580               (use (reg:SI DIRFLAG_REG))])]
18581   "TARGET_SINGLE_STRINGOP || optimize_size"
18582   "")
18584 (define_insn "*strsetdi_rex_1"
18585   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18586         (match_operand:DI 2 "register_operand" "a"))
18587    (set (match_operand:DI 0 "register_operand" "=D")
18588         (plus:DI (match_dup 1)
18589                  (const_int 8)))
18590    (use (reg:SI DIRFLAG_REG))]
18591   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18592   "stosq"
18593   [(set_attr "type" "str")
18594    (set_attr "memory" "store")
18595    (set_attr "mode" "DI")])
18597 (define_insn "*strsetsi_1"
18598   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18599         (match_operand:SI 2 "register_operand" "a"))
18600    (set (match_operand:SI 0 "register_operand" "=D")
18601         (plus:SI (match_dup 1)
18602                  (const_int 4)))
18603    (use (reg:SI DIRFLAG_REG))]
18604   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18605   "{stosl|stosd}"
18606   [(set_attr "type" "str")
18607    (set_attr "memory" "store")
18608    (set_attr "mode" "SI")])
18610 (define_insn "*strsetsi_rex_1"
18611   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18612         (match_operand:SI 2 "register_operand" "a"))
18613    (set (match_operand:DI 0 "register_operand" "=D")
18614         (plus:DI (match_dup 1)
18615                  (const_int 4)))
18616    (use (reg:SI DIRFLAG_REG))]
18617   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18618   "{stosl|stosd}"
18619   [(set_attr "type" "str")
18620    (set_attr "memory" "store")
18621    (set_attr "mode" "SI")])
18623 (define_insn "*strsethi_1"
18624   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18625         (match_operand:HI 2 "register_operand" "a"))
18626    (set (match_operand:SI 0 "register_operand" "=D")
18627         (plus:SI (match_dup 1)
18628                  (const_int 2)))
18629    (use (reg:SI DIRFLAG_REG))]
18630   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18631   "stosw"
18632   [(set_attr "type" "str")
18633    (set_attr "memory" "store")
18634    (set_attr "mode" "HI")])
18636 (define_insn "*strsethi_rex_1"
18637   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18638         (match_operand:HI 2 "register_operand" "a"))
18639    (set (match_operand:DI 0 "register_operand" "=D")
18640         (plus:DI (match_dup 1)
18641                  (const_int 2)))
18642    (use (reg:SI DIRFLAG_REG))]
18643   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18644   "stosw"
18645   [(set_attr "type" "str")
18646    (set_attr "memory" "store")
18647    (set_attr "mode" "HI")])
18649 (define_insn "*strsetqi_1"
18650   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18651         (match_operand:QI 2 "register_operand" "a"))
18652    (set (match_operand:SI 0 "register_operand" "=D")
18653         (plus:SI (match_dup 1)
18654                  (const_int 1)))
18655    (use (reg:SI DIRFLAG_REG))]
18656   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18657   "stosb"
18658   [(set_attr "type" "str")
18659    (set_attr "memory" "store")
18660    (set_attr "mode" "QI")])
18662 (define_insn "*strsetqi_rex_1"
18663   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18664         (match_operand:QI 2 "register_operand" "a"))
18665    (set (match_operand:DI 0 "register_operand" "=D")
18666         (plus:DI (match_dup 1)
18667                  (const_int 1)))
18668    (use (reg:SI DIRFLAG_REG))]
18669   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18670   "stosb"
18671   [(set_attr "type" "str")
18672    (set_attr "memory" "store")
18673    (set_attr "mode" "QI")])
18675 (define_expand "rep_stos"
18676   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18677               (set (match_operand 0 "register_operand" "")
18678                    (match_operand 4 "" ""))
18679               (set (match_operand 2 "memory_operand" "") (const_int 0))
18680               (use (match_operand 3 "register_operand" ""))
18681               (use (match_dup 1))
18682               (use (reg:SI DIRFLAG_REG))])]
18683   ""
18684   "")
18686 (define_insn "*rep_stosdi_rex64"
18687   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18688    (set (match_operand:DI 0 "register_operand" "=D")
18689         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18690                             (const_int 3))
18691                  (match_operand:DI 3 "register_operand" "0")))
18692    (set (mem:BLK (match_dup 3))
18693         (const_int 0))
18694    (use (match_operand:DI 2 "register_operand" "a"))
18695    (use (match_dup 4))
18696    (use (reg:SI DIRFLAG_REG))]
18697   "TARGET_64BIT"
18698   "{rep\;stosq|rep stosq}"
18699   [(set_attr "type" "str")
18700    (set_attr "prefix_rep" "1")
18701    (set_attr "memory" "store")
18702    (set_attr "mode" "DI")])
18704 (define_insn "*rep_stossi"
18705   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18706    (set (match_operand:SI 0 "register_operand" "=D")
18707         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18708                             (const_int 2))
18709                  (match_operand:SI 3 "register_operand" "0")))
18710    (set (mem:BLK (match_dup 3))
18711         (const_int 0))
18712    (use (match_operand:SI 2 "register_operand" "a"))
18713    (use (match_dup 4))
18714    (use (reg:SI DIRFLAG_REG))]
18715   "!TARGET_64BIT"
18716   "{rep\;stosl|rep stosd}"
18717   [(set_attr "type" "str")
18718    (set_attr "prefix_rep" "1")
18719    (set_attr "memory" "store")
18720    (set_attr "mode" "SI")])
18722 (define_insn "*rep_stossi_rex64"
18723   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18724    (set (match_operand:DI 0 "register_operand" "=D")
18725         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18726                             (const_int 2))
18727                  (match_operand:DI 3 "register_operand" "0")))
18728    (set (mem:BLK (match_dup 3))
18729         (const_int 0))
18730    (use (match_operand:SI 2 "register_operand" "a"))
18731    (use (match_dup 4))
18732    (use (reg:SI DIRFLAG_REG))]
18733   "TARGET_64BIT"
18734   "{rep\;stosl|rep stosd}"
18735   [(set_attr "type" "str")
18736    (set_attr "prefix_rep" "1")
18737    (set_attr "memory" "store")
18738    (set_attr "mode" "SI")])
18740 (define_insn "*rep_stosqi"
18741   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18742    (set (match_operand:SI 0 "register_operand" "=D")
18743         (plus:SI (match_operand:SI 3 "register_operand" "0")
18744                  (match_operand:SI 4 "register_operand" "1")))
18745    (set (mem:BLK (match_dup 3))
18746         (const_int 0))
18747    (use (match_operand:QI 2 "register_operand" "a"))
18748    (use (match_dup 4))
18749    (use (reg:SI DIRFLAG_REG))]
18750   "!TARGET_64BIT"
18751   "{rep\;stosb|rep stosb}"
18752   [(set_attr "type" "str")
18753    (set_attr "prefix_rep" "1")
18754    (set_attr "memory" "store")
18755    (set_attr "mode" "QI")])
18757 (define_insn "*rep_stosqi_rex64"
18758   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18759    (set (match_operand:DI 0 "register_operand" "=D")
18760         (plus:DI (match_operand:DI 3 "register_operand" "0")
18761                  (match_operand:DI 4 "register_operand" "1")))
18762    (set (mem:BLK (match_dup 3))
18763         (const_int 0))
18764    (use (match_operand:QI 2 "register_operand" "a"))
18765    (use (match_dup 4))
18766    (use (reg:SI DIRFLAG_REG))]
18767   "TARGET_64BIT"
18768   "{rep\;stosb|rep stosb}"
18769   [(set_attr "type" "str")
18770    (set_attr "prefix_rep" "1")
18771    (set_attr "memory" "store")
18772    (set_attr "mode" "QI")])
18774 (define_expand "cmpstrnsi"
18775   [(set (match_operand:SI 0 "register_operand" "")
18776         (compare:SI (match_operand:BLK 1 "general_operand" "")
18777                     (match_operand:BLK 2 "general_operand" "")))
18778    (use (match_operand 3 "general_operand" ""))
18779    (use (match_operand 4 "immediate_operand" ""))]
18780   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18782   rtx addr1, addr2, out, outlow, count, countreg, align;
18784   /* Can't use this if the user has appropriated esi or edi.  */
18785   if (global_regs[4] || global_regs[5])
18786     FAIL;
18788   out = operands[0];
18789   if (GET_CODE (out) != REG)
18790     out = gen_reg_rtx (SImode);
18792   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18793   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18794   if (addr1 != XEXP (operands[1], 0))
18795     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18796   if (addr2 != XEXP (operands[2], 0))
18797     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18799   count = operands[3];
18800   countreg = ix86_zero_extend_to_Pmode (count);
18802   /* %%% Iff we are testing strict equality, we can use known alignment
18803      to good advantage.  This may be possible with combine, particularly
18804      once cc0 is dead.  */
18805   align = operands[4];
18807   emit_insn (gen_cld ());
18808   if (GET_CODE (count) == CONST_INT)
18809     {
18810       if (INTVAL (count) == 0)
18811         {
18812           emit_move_insn (operands[0], const0_rtx);
18813           DONE;
18814         }
18815       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18816                                      operands[1], operands[2]));
18817     }
18818   else
18819     {
18820       if (TARGET_64BIT)
18821         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18822       else
18823         emit_insn (gen_cmpsi_1 (countreg, countreg));
18824       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18825                                   operands[1], operands[2]));
18826     }
18828   outlow = gen_lowpart (QImode, out);
18829   emit_insn (gen_cmpintqi (outlow));
18830   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18832   if (operands[0] != out)
18833     emit_move_insn (operands[0], out);
18835   DONE;
18838 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18840 (define_expand "cmpintqi"
18841   [(set (match_dup 1)
18842         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18843    (set (match_dup 2)
18844         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18845    (parallel [(set (match_operand:QI 0 "register_operand" "")
18846                    (minus:QI (match_dup 1)
18847                              (match_dup 2)))
18848               (clobber (reg:CC FLAGS_REG))])]
18849   ""
18850   "operands[1] = gen_reg_rtx (QImode);
18851    operands[2] = gen_reg_rtx (QImode);")
18853 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18854 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18856 (define_expand "cmpstrnqi_nz_1"
18857   [(parallel [(set (reg:CC FLAGS_REG)
18858                    (compare:CC (match_operand 4 "memory_operand" "")
18859                                (match_operand 5 "memory_operand" "")))
18860               (use (match_operand 2 "register_operand" ""))
18861               (use (match_operand:SI 3 "immediate_operand" ""))
18862               (use (reg:SI DIRFLAG_REG))
18863               (clobber (match_operand 0 "register_operand" ""))
18864               (clobber (match_operand 1 "register_operand" ""))
18865               (clobber (match_dup 2))])]
18866   ""
18867   "")
18869 (define_insn "*cmpstrnqi_nz_1"
18870   [(set (reg:CC FLAGS_REG)
18871         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18872                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18873    (use (match_operand:SI 6 "register_operand" "2"))
18874    (use (match_operand:SI 3 "immediate_operand" "i"))
18875    (use (reg:SI DIRFLAG_REG))
18876    (clobber (match_operand:SI 0 "register_operand" "=S"))
18877    (clobber (match_operand:SI 1 "register_operand" "=D"))
18878    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18879   "!TARGET_64BIT"
18880   "repz{\;| }cmpsb"
18881   [(set_attr "type" "str")
18882    (set_attr "mode" "QI")
18883    (set_attr "prefix_rep" "1")])
18885 (define_insn "*cmpstrnqi_nz_rex_1"
18886   [(set (reg:CC FLAGS_REG)
18887         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18888                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18889    (use (match_operand:DI 6 "register_operand" "2"))
18890    (use (match_operand:SI 3 "immediate_operand" "i"))
18891    (use (reg:SI DIRFLAG_REG))
18892    (clobber (match_operand:DI 0 "register_operand" "=S"))
18893    (clobber (match_operand:DI 1 "register_operand" "=D"))
18894    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18895   "TARGET_64BIT"
18896   "repz{\;| }cmpsb"
18897   [(set_attr "type" "str")
18898    (set_attr "mode" "QI")
18899    (set_attr "prefix_rep" "1")])
18901 ;; The same, but the count is not known to not be zero.
18903 (define_expand "cmpstrnqi_1"
18904   [(parallel [(set (reg:CC FLAGS_REG)
18905                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18906                                      (const_int 0))
18907                   (compare:CC (match_operand 4 "memory_operand" "")
18908                               (match_operand 5 "memory_operand" ""))
18909                   (const_int 0)))
18910               (use (match_operand:SI 3 "immediate_operand" ""))
18911               (use (reg:CC FLAGS_REG))
18912               (use (reg:SI DIRFLAG_REG))
18913               (clobber (match_operand 0 "register_operand" ""))
18914               (clobber (match_operand 1 "register_operand" ""))
18915               (clobber (match_dup 2))])]
18916   ""
18917   "")
18919 (define_insn "*cmpstrnqi_1"
18920   [(set (reg:CC FLAGS_REG)
18921         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18922                              (const_int 0))
18923           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18924                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18925           (const_int 0)))
18926    (use (match_operand:SI 3 "immediate_operand" "i"))
18927    (use (reg:CC FLAGS_REG))
18928    (use (reg:SI DIRFLAG_REG))
18929    (clobber (match_operand:SI 0 "register_operand" "=S"))
18930    (clobber (match_operand:SI 1 "register_operand" "=D"))
18931    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18932   "!TARGET_64BIT"
18933   "repz{\;| }cmpsb"
18934   [(set_attr "type" "str")
18935    (set_attr "mode" "QI")
18936    (set_attr "prefix_rep" "1")])
18938 (define_insn "*cmpstrnqi_rex_1"
18939   [(set (reg:CC FLAGS_REG)
18940         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18941                              (const_int 0))
18942           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18943                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18944           (const_int 0)))
18945    (use (match_operand:SI 3 "immediate_operand" "i"))
18946    (use (reg:CC FLAGS_REG))
18947    (use (reg:SI DIRFLAG_REG))
18948    (clobber (match_operand:DI 0 "register_operand" "=S"))
18949    (clobber (match_operand:DI 1 "register_operand" "=D"))
18950    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18951   "TARGET_64BIT"
18952   "repz{\;| }cmpsb"
18953   [(set_attr "type" "str")
18954    (set_attr "mode" "QI")
18955    (set_attr "prefix_rep" "1")])
18957 (define_expand "strlensi"
18958   [(set (match_operand:SI 0 "register_operand" "")
18959         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18960                     (match_operand:QI 2 "immediate_operand" "")
18961                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18962   ""
18964  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18965    DONE;
18966  else
18967    FAIL;
18970 (define_expand "strlendi"
18971   [(set (match_operand:DI 0 "register_operand" "")
18972         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18973                     (match_operand:QI 2 "immediate_operand" "")
18974                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18975   ""
18977  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18978    DONE;
18979  else
18980    FAIL;
18983 (define_expand "strlenqi_1"
18984   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18985               (use (reg:SI DIRFLAG_REG))
18986               (clobber (match_operand 1 "register_operand" ""))
18987               (clobber (reg:CC FLAGS_REG))])]
18988   ""
18989   "")
18991 (define_insn "*strlenqi_1"
18992   [(set (match_operand:SI 0 "register_operand" "=&c")
18993         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18994                     (match_operand:QI 2 "register_operand" "a")
18995                     (match_operand:SI 3 "immediate_operand" "i")
18996                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18997    (use (reg:SI DIRFLAG_REG))
18998    (clobber (match_operand:SI 1 "register_operand" "=D"))
18999    (clobber (reg:CC FLAGS_REG))]
19000   "!TARGET_64BIT"
19001   "repnz{\;| }scasb"
19002   [(set_attr "type" "str")
19003    (set_attr "mode" "QI")
19004    (set_attr "prefix_rep" "1")])
19006 (define_insn "*strlenqi_rex_1"
19007   [(set (match_operand:DI 0 "register_operand" "=&c")
19008         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19009                     (match_operand:QI 2 "register_operand" "a")
19010                     (match_operand:DI 3 "immediate_operand" "i")
19011                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19012    (use (reg:SI DIRFLAG_REG))
19013    (clobber (match_operand:DI 1 "register_operand" "=D"))
19014    (clobber (reg:CC FLAGS_REG))]
19015   "TARGET_64BIT"
19016   "repnz{\;| }scasb"
19017   [(set_attr "type" "str")
19018    (set_attr "mode" "QI")
19019    (set_attr "prefix_rep" "1")])
19021 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19022 ;; handled in combine, but it is not currently up to the task.
19023 ;; When used for their truth value, the cmpstrn* expanders generate
19024 ;; code like this:
19026 ;;   repz cmpsb
19027 ;;   seta       %al
19028 ;;   setb       %dl
19029 ;;   cmpb       %al, %dl
19030 ;;   jcc        label
19032 ;; The intermediate three instructions are unnecessary.
19034 ;; This one handles cmpstrn*_nz_1...
19035 (define_peephole2
19036   [(parallel[
19037      (set (reg:CC FLAGS_REG)
19038           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19039                       (mem:BLK (match_operand 5 "register_operand" ""))))
19040      (use (match_operand 6 "register_operand" ""))
19041      (use (match_operand:SI 3 "immediate_operand" ""))
19042      (use (reg:SI DIRFLAG_REG))
19043      (clobber (match_operand 0 "register_operand" ""))
19044      (clobber (match_operand 1 "register_operand" ""))
19045      (clobber (match_operand 2 "register_operand" ""))])
19046    (set (match_operand:QI 7 "register_operand" "")
19047         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19048    (set (match_operand:QI 8 "register_operand" "")
19049         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19050    (set (reg FLAGS_REG)
19051         (compare (match_dup 7) (match_dup 8)))
19052   ]
19053   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19054   [(parallel[
19055      (set (reg:CC FLAGS_REG)
19056           (compare:CC (mem:BLK (match_dup 4))
19057                       (mem:BLK (match_dup 5))))
19058      (use (match_dup 6))
19059      (use (match_dup 3))
19060      (use (reg:SI DIRFLAG_REG))
19061      (clobber (match_dup 0))
19062      (clobber (match_dup 1))
19063      (clobber (match_dup 2))])]
19064   "")
19066 ;; ...and this one handles cmpstrn*_1.
19067 (define_peephole2
19068   [(parallel[
19069      (set (reg:CC FLAGS_REG)
19070           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19071                                (const_int 0))
19072             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19073                         (mem:BLK (match_operand 5 "register_operand" "")))
19074             (const_int 0)))
19075      (use (match_operand:SI 3 "immediate_operand" ""))
19076      (use (reg:CC FLAGS_REG))
19077      (use (reg:SI DIRFLAG_REG))
19078      (clobber (match_operand 0 "register_operand" ""))
19079      (clobber (match_operand 1 "register_operand" ""))
19080      (clobber (match_operand 2 "register_operand" ""))])
19081    (set (match_operand:QI 7 "register_operand" "")
19082         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19083    (set (match_operand:QI 8 "register_operand" "")
19084         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19085    (set (reg FLAGS_REG)
19086         (compare (match_dup 7) (match_dup 8)))
19087   ]
19088   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19089   [(parallel[
19090      (set (reg:CC FLAGS_REG)
19091           (if_then_else:CC (ne (match_dup 6)
19092                                (const_int 0))
19093             (compare:CC (mem:BLK (match_dup 4))
19094                         (mem:BLK (match_dup 5)))
19095             (const_int 0)))
19096      (use (match_dup 3))
19097      (use (reg:CC FLAGS_REG))
19098      (use (reg:SI DIRFLAG_REG))
19099      (clobber (match_dup 0))
19100      (clobber (match_dup 1))
19101      (clobber (match_dup 2))])]
19102   "")
19106 ;; Conditional move instructions.
19108 (define_expand "movdicc"
19109   [(set (match_operand:DI 0 "register_operand" "")
19110         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19111                          (match_operand:DI 2 "general_operand" "")
19112                          (match_operand:DI 3 "general_operand" "")))]
19113   "TARGET_64BIT"
19114   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19116 (define_insn "x86_movdicc_0_m1_rex64"
19117   [(set (match_operand:DI 0 "register_operand" "=r")
19118         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19119           (const_int -1)
19120           (const_int 0)))
19121    (clobber (reg:CC FLAGS_REG))]
19122   "TARGET_64BIT"
19123   "sbb{q}\t%0, %0"
19124   ; Since we don't have the proper number of operands for an alu insn,
19125   ; fill in all the blanks.
19126   [(set_attr "type" "alu")
19127    (set_attr "pent_pair" "pu")
19128    (set_attr "memory" "none")
19129    (set_attr "imm_disp" "false")
19130    (set_attr "mode" "DI")
19131    (set_attr "length_immediate" "0")])
19133 (define_insn "*movdicc_c_rex64"
19134   [(set (match_operand:DI 0 "register_operand" "=r,r")
19135         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19136                                 [(reg FLAGS_REG) (const_int 0)])
19137                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19138                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19139   "TARGET_64BIT && TARGET_CMOVE
19140    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19141   "@
19142    cmov%O2%C1\t{%2, %0|%0, %2}
19143    cmov%O2%c1\t{%3, %0|%0, %3}"
19144   [(set_attr "type" "icmov")
19145    (set_attr "mode" "DI")])
19147 (define_expand "movsicc"
19148   [(set (match_operand:SI 0 "register_operand" "")
19149         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19150                          (match_operand:SI 2 "general_operand" "")
19151                          (match_operand:SI 3 "general_operand" "")))]
19152   ""
19153   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19155 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19156 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19157 ;; So just document what we're doing explicitly.
19159 (define_insn "x86_movsicc_0_m1"
19160   [(set (match_operand:SI 0 "register_operand" "=r")
19161         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19162           (const_int -1)
19163           (const_int 0)))
19164    (clobber (reg:CC FLAGS_REG))]
19165   ""
19166   "sbb{l}\t%0, %0"
19167   ; Since we don't have the proper number of operands for an alu insn,
19168   ; fill in all the blanks.
19169   [(set_attr "type" "alu")
19170    (set_attr "pent_pair" "pu")
19171    (set_attr "memory" "none")
19172    (set_attr "imm_disp" "false")
19173    (set_attr "mode" "SI")
19174    (set_attr "length_immediate" "0")])
19176 (define_insn "*movsicc_noc"
19177   [(set (match_operand:SI 0 "register_operand" "=r,r")
19178         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19179                                 [(reg FLAGS_REG) (const_int 0)])
19180                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19181                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19182   "TARGET_CMOVE
19183    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19184   "@
19185    cmov%O2%C1\t{%2, %0|%0, %2}
19186    cmov%O2%c1\t{%3, %0|%0, %3}"
19187   [(set_attr "type" "icmov")
19188    (set_attr "mode" "SI")])
19190 (define_expand "movhicc"
19191   [(set (match_operand:HI 0 "register_operand" "")
19192         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19193                          (match_operand:HI 2 "general_operand" "")
19194                          (match_operand:HI 3 "general_operand" "")))]
19195   "TARGET_HIMODE_MATH"
19196   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19198 (define_insn "*movhicc_noc"
19199   [(set (match_operand:HI 0 "register_operand" "=r,r")
19200         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19201                                 [(reg FLAGS_REG) (const_int 0)])
19202                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19203                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19204   "TARGET_CMOVE
19205    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19206   "@
19207    cmov%O2%C1\t{%2, %0|%0, %2}
19208    cmov%O2%c1\t{%3, %0|%0, %3}"
19209   [(set_attr "type" "icmov")
19210    (set_attr "mode" "HI")])
19212 (define_expand "movqicc"
19213   [(set (match_operand:QI 0 "register_operand" "")
19214         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19215                          (match_operand:QI 2 "general_operand" "")
19216                          (match_operand:QI 3 "general_operand" "")))]
19217   "TARGET_QIMODE_MATH"
19218   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19220 (define_insn_and_split "*movqicc_noc"
19221   [(set (match_operand:QI 0 "register_operand" "=r,r")
19222         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19223                                 [(match_operand 4 "flags_reg_operand" "")
19224                                  (const_int 0)])
19225                       (match_operand:QI 2 "register_operand" "r,0")
19226                       (match_operand:QI 3 "register_operand" "0,r")))]
19227   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19228   "#"
19229   "&& reload_completed"
19230   [(set (match_dup 0)
19231         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19232                       (match_dup 2)
19233                       (match_dup 3)))]
19234   "operands[0] = gen_lowpart (SImode, operands[0]);
19235    operands[2] = gen_lowpart (SImode, operands[2]);
19236    operands[3] = gen_lowpart (SImode, operands[3]);"
19237   [(set_attr "type" "icmov")
19238    (set_attr "mode" "SI")])
19240 (define_expand "movsfcc"
19241   [(set (match_operand:SF 0 "register_operand" "")
19242         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19243                          (match_operand:SF 2 "register_operand" "")
19244                          (match_operand:SF 3 "register_operand" "")))]
19245   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19246   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19248 (define_insn "*movsfcc_1_387"
19249   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19250         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19251                                 [(reg FLAGS_REG) (const_int 0)])
19252                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19253                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19254   "TARGET_80387 && TARGET_CMOVE
19255    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19256   "@
19257    fcmov%F1\t{%2, %0|%0, %2}
19258    fcmov%f1\t{%3, %0|%0, %3}
19259    cmov%O2%C1\t{%2, %0|%0, %2}
19260    cmov%O2%c1\t{%3, %0|%0, %3}"
19261   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19262    (set_attr "mode" "SF,SF,SI,SI")])
19264 (define_expand "movdfcc"
19265   [(set (match_operand:DF 0 "register_operand" "")
19266         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19267                          (match_operand:DF 2 "register_operand" "")
19268                          (match_operand:DF 3 "register_operand" "")))]
19269   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19270   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19272 (define_insn "*movdfcc_1"
19273   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19274         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19275                                 [(reg FLAGS_REG) (const_int 0)])
19276                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19277                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19278   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19279    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19280   "@
19281    fcmov%F1\t{%2, %0|%0, %2}
19282    fcmov%f1\t{%3, %0|%0, %3}
19283    #
19284    #"
19285   [(set_attr "type" "fcmov,fcmov,multi,multi")
19286    (set_attr "mode" "DF")])
19288 (define_insn "*movdfcc_1_rex64"
19289   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19290         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19291                                 [(reg FLAGS_REG) (const_int 0)])
19292                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19293                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19294   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19295    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19296   "@
19297    fcmov%F1\t{%2, %0|%0, %2}
19298    fcmov%f1\t{%3, %0|%0, %3}
19299    cmov%O2%C1\t{%2, %0|%0, %2}
19300    cmov%O2%c1\t{%3, %0|%0, %3}"
19301   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19302    (set_attr "mode" "DF")])
19304 (define_split
19305   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19306         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19307                                 [(match_operand 4 "flags_reg_operand" "")
19308                                  (const_int 0)])
19309                       (match_operand:DF 2 "nonimmediate_operand" "")
19310                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19311   "!TARGET_64BIT && reload_completed"
19312   [(set (match_dup 2)
19313         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19314                       (match_dup 5)
19315                       (match_dup 7)))
19316    (set (match_dup 3)
19317         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19318                       (match_dup 6)
19319                       (match_dup 8)))]
19320   "split_di (operands+2, 1, operands+5, operands+6);
19321    split_di (operands+3, 1, operands+7, operands+8);
19322    split_di (operands, 1, operands+2, operands+3);")
19324 (define_expand "movxfcc"
19325   [(set (match_operand:XF 0 "register_operand" "")
19326         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19327                          (match_operand:XF 2 "register_operand" "")
19328                          (match_operand:XF 3 "register_operand" "")))]
19329   "TARGET_80387 && TARGET_CMOVE"
19330   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19332 (define_insn "*movxfcc_1"
19333   [(set (match_operand:XF 0 "register_operand" "=f,f")
19334         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19335                                 [(reg FLAGS_REG) (const_int 0)])
19336                       (match_operand:XF 2 "register_operand" "f,0")
19337                       (match_operand:XF 3 "register_operand" "0,f")))]
19338   "TARGET_80387 && TARGET_CMOVE"
19339   "@
19340    fcmov%F1\t{%2, %0|%0, %2}
19341    fcmov%f1\t{%3, %0|%0, %3}"
19342   [(set_attr "type" "fcmov")
19343    (set_attr "mode" "XF")])
19345 ;; These versions of the min/max patterns are intentionally ignorant of
19346 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19347 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19348 ;; are undefined in this condition, we're certain this is correct.
19350 (define_insn "sminsf3"
19351   [(set (match_operand:SF 0 "register_operand" "=x")
19352         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19353                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19354   "TARGET_SSE_MATH"
19355   "minss\t{%2, %0|%0, %2}"
19356   [(set_attr "type" "sseadd")
19357    (set_attr "mode" "SF")])
19359 (define_insn "smaxsf3"
19360   [(set (match_operand:SF 0 "register_operand" "=x")
19361         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19362                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19363   "TARGET_SSE_MATH"
19364   "maxss\t{%2, %0|%0, %2}"
19365   [(set_attr "type" "sseadd")
19366    (set_attr "mode" "SF")])
19368 (define_insn "smindf3"
19369   [(set (match_operand:DF 0 "register_operand" "=x")
19370         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19371                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19372   "TARGET_SSE2 && TARGET_SSE_MATH"
19373   "minsd\t{%2, %0|%0, %2}"
19374   [(set_attr "type" "sseadd")
19375    (set_attr "mode" "DF")])
19377 (define_insn "smaxdf3"
19378   [(set (match_operand:DF 0 "register_operand" "=x")
19379         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19380                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19381   "TARGET_SSE2 && TARGET_SSE_MATH"
19382   "maxsd\t{%2, %0|%0, %2}"
19383   [(set_attr "type" "sseadd")
19384    (set_attr "mode" "DF")])
19386 ;; These versions of the min/max patterns implement exactly the operations
19387 ;;   min = (op1 < op2 ? op1 : op2)
19388 ;;   max = (!(op1 < op2) ? op1 : op2)
19389 ;; Their operands are not commutative, and thus they may be used in the
19390 ;; presence of -0.0 and NaN.
19392 (define_insn "*ieee_sminsf3"
19393   [(set (match_operand:SF 0 "register_operand" "=x")
19394         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19395                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19396                    UNSPEC_IEEE_MIN))]
19397   "TARGET_SSE_MATH"
19398   "minss\t{%2, %0|%0, %2}"
19399   [(set_attr "type" "sseadd")
19400    (set_attr "mode" "SF")])
19402 (define_insn "*ieee_smaxsf3"
19403   [(set (match_operand:SF 0 "register_operand" "=x")
19404         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19405                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19406                    UNSPEC_IEEE_MAX))]
19407   "TARGET_SSE_MATH"
19408   "maxss\t{%2, %0|%0, %2}"
19409   [(set_attr "type" "sseadd")
19410    (set_attr "mode" "SF")])
19412 (define_insn "*ieee_smindf3"
19413   [(set (match_operand:DF 0 "register_operand" "=x")
19414         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19415                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19416                    UNSPEC_IEEE_MIN))]
19417   "TARGET_SSE2 && TARGET_SSE_MATH"
19418   "minsd\t{%2, %0|%0, %2}"
19419   [(set_attr "type" "sseadd")
19420    (set_attr "mode" "DF")])
19422 (define_insn "*ieee_smaxdf3"
19423   [(set (match_operand:DF 0 "register_operand" "=x")
19424         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19425                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19426                    UNSPEC_IEEE_MAX))]
19427   "TARGET_SSE2 && TARGET_SSE_MATH"
19428   "maxsd\t{%2, %0|%0, %2}"
19429   [(set_attr "type" "sseadd")
19430    (set_attr "mode" "DF")])
19432 ;; Make two stack loads independent:
19433 ;;   fld aa              fld aa
19434 ;;   fld %st(0)     ->   fld bb
19435 ;;   fmul bb             fmul %st(1), %st
19437 ;; Actually we only match the last two instructions for simplicity.
19438 (define_peephole2
19439   [(set (match_operand 0 "fp_register_operand" "")
19440         (match_operand 1 "fp_register_operand" ""))
19441    (set (match_dup 0)
19442         (match_operator 2 "binary_fp_operator"
19443            [(match_dup 0)
19444             (match_operand 3 "memory_operand" "")]))]
19445   "REGNO (operands[0]) != REGNO (operands[1])"
19446   [(set (match_dup 0) (match_dup 3))
19447    (set (match_dup 0) (match_dup 4))]
19449   ;; The % modifier is not operational anymore in peephole2's, so we have to
19450   ;; swap the operands manually in the case of addition and multiplication.
19451   "if (COMMUTATIVE_ARITH_P (operands[2]))
19452      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19453                                  operands[0], operands[1]);
19454    else
19455      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19456                                  operands[1], operands[0]);")
19458 ;; Conditional addition patterns
19459 (define_expand "addqicc"
19460   [(match_operand:QI 0 "register_operand" "")
19461    (match_operand 1 "comparison_operator" "")
19462    (match_operand:QI 2 "register_operand" "")
19463    (match_operand:QI 3 "const_int_operand" "")]
19464   ""
19465   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19467 (define_expand "addhicc"
19468   [(match_operand:HI 0 "register_operand" "")
19469    (match_operand 1 "comparison_operator" "")
19470    (match_operand:HI 2 "register_operand" "")
19471    (match_operand:HI 3 "const_int_operand" "")]
19472   ""
19473   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19475 (define_expand "addsicc"
19476   [(match_operand:SI 0 "register_operand" "")
19477    (match_operand 1 "comparison_operator" "")
19478    (match_operand:SI 2 "register_operand" "")
19479    (match_operand:SI 3 "const_int_operand" "")]
19480   ""
19481   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19483 (define_expand "adddicc"
19484   [(match_operand:DI 0 "register_operand" "")
19485    (match_operand 1 "comparison_operator" "")
19486    (match_operand:DI 2 "register_operand" "")
19487    (match_operand:DI 3 "const_int_operand" "")]
19488   "TARGET_64BIT"
19489   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19492 ;; Misc patterns (?)
19494 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19495 ;; Otherwise there will be nothing to keep
19497 ;; [(set (reg ebp) (reg esp))]
19498 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19499 ;;  (clobber (eflags)]
19500 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19502 ;; in proper program order.
19503 (define_insn "pro_epilogue_adjust_stack_1"
19504   [(set (match_operand:SI 0 "register_operand" "=r,r")
19505         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19506                  (match_operand:SI 2 "immediate_operand" "i,i")))
19507    (clobber (reg:CC FLAGS_REG))
19508    (clobber (mem:BLK (scratch)))]
19509   "!TARGET_64BIT"
19511   switch (get_attr_type (insn))
19512     {
19513     case TYPE_IMOV:
19514       return "mov{l}\t{%1, %0|%0, %1}";
19516     case TYPE_ALU:
19517       if (GET_CODE (operands[2]) == CONST_INT
19518           && (INTVAL (operands[2]) == 128
19519               || (INTVAL (operands[2]) < 0
19520                   && INTVAL (operands[2]) != -128)))
19521         {
19522           operands[2] = GEN_INT (-INTVAL (operands[2]));
19523           return "sub{l}\t{%2, %0|%0, %2}";
19524         }
19525       return "add{l}\t{%2, %0|%0, %2}";
19527     case TYPE_LEA:
19528       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19529       return "lea{l}\t{%a2, %0|%0, %a2}";
19531     default:
19532       gcc_unreachable ();
19533     }
19535   [(set (attr "type")
19536         (cond [(eq_attr "alternative" "0")
19537                  (const_string "alu")
19538                (match_operand:SI 2 "const0_operand" "")
19539                  (const_string "imov")
19540               ]
19541               (const_string "lea")))
19542    (set_attr "mode" "SI")])
19544 (define_insn "pro_epilogue_adjust_stack_rex64"
19545   [(set (match_operand:DI 0 "register_operand" "=r,r")
19546         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19547                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19548    (clobber (reg:CC FLAGS_REG))
19549    (clobber (mem:BLK (scratch)))]
19550   "TARGET_64BIT"
19552   switch (get_attr_type (insn))
19553     {
19554     case TYPE_IMOV:
19555       return "mov{q}\t{%1, %0|%0, %1}";
19557     case TYPE_ALU:
19558       if (GET_CODE (operands[2]) == CONST_INT
19559           /* Avoid overflows.  */
19560           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19561           && (INTVAL (operands[2]) == 128
19562               || (INTVAL (operands[2]) < 0
19563                   && INTVAL (operands[2]) != -128)))
19564         {
19565           operands[2] = GEN_INT (-INTVAL (operands[2]));
19566           return "sub{q}\t{%2, %0|%0, %2}";
19567         }
19568       return "add{q}\t{%2, %0|%0, %2}";
19570     case TYPE_LEA:
19571       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19572       return "lea{q}\t{%a2, %0|%0, %a2}";
19574     default:
19575       gcc_unreachable ();
19576     }
19578   [(set (attr "type")
19579         (cond [(eq_attr "alternative" "0")
19580                  (const_string "alu")
19581                (match_operand:DI 2 "const0_operand" "")
19582                  (const_string "imov")
19583               ]
19584               (const_string "lea")))
19585    (set_attr "mode" "DI")])
19587 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19588   [(set (match_operand:DI 0 "register_operand" "=r,r")
19589         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19590                  (match_operand:DI 3 "immediate_operand" "i,i")))
19591    (use (match_operand:DI 2 "register_operand" "r,r"))
19592    (clobber (reg:CC FLAGS_REG))
19593    (clobber (mem:BLK (scratch)))]
19594   "TARGET_64BIT"
19596   switch (get_attr_type (insn))
19597     {
19598     case TYPE_ALU:
19599       return "add{q}\t{%2, %0|%0, %2}";
19601     case TYPE_LEA:
19602       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19603       return "lea{q}\t{%a2, %0|%0, %a2}";
19605     default:
19606       gcc_unreachable ();
19607     }
19609   [(set_attr "type" "alu,lea")
19610    (set_attr "mode" "DI")])
19612 (define_expand "allocate_stack_worker"
19613   [(match_operand:SI 0 "register_operand" "")]
19614   "TARGET_STACK_PROBE"
19616   if (reload_completed)
19617     {
19618       if (TARGET_64BIT)
19619         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19620       else
19621         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19622     }
19623   else
19624     {
19625       if (TARGET_64BIT)
19626         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19627       else
19628         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19629     }
19630   DONE;
19633 (define_insn "allocate_stack_worker_1"
19634   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19635     UNSPECV_STACK_PROBE)
19636    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19637    (clobber (match_scratch:SI 1 "=0"))
19638    (clobber (reg:CC FLAGS_REG))]
19639   "!TARGET_64BIT && TARGET_STACK_PROBE"
19640   "call\t__alloca"
19641   [(set_attr "type" "multi")
19642    (set_attr "length" "5")])
19644 (define_expand "allocate_stack_worker_postreload"
19645   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19646                                     UNSPECV_STACK_PROBE)
19647               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19648               (clobber (match_dup 0))
19649               (clobber (reg:CC FLAGS_REG))])]
19650   ""
19651   "")
19653 (define_insn "allocate_stack_worker_rex64"
19654   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19655     UNSPECV_STACK_PROBE)
19656    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19657    (clobber (match_scratch:DI 1 "=0"))
19658    (clobber (reg:CC FLAGS_REG))]
19659   "TARGET_64BIT && TARGET_STACK_PROBE"
19660   "call\t__alloca"
19661   [(set_attr "type" "multi")
19662    (set_attr "length" "5")])
19664 (define_expand "allocate_stack_worker_rex64_postreload"
19665   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19666                                     UNSPECV_STACK_PROBE)
19667               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19668               (clobber (match_dup 0))
19669               (clobber (reg:CC FLAGS_REG))])]
19670   ""
19671   "")
19673 (define_expand "allocate_stack"
19674   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19675                    (minus:SI (reg:SI SP_REG)
19676                              (match_operand:SI 1 "general_operand" "")))
19677               (clobber (reg:CC FLAGS_REG))])
19678    (parallel [(set (reg:SI SP_REG)
19679                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19680               (clobber (reg:CC FLAGS_REG))])]
19681   "TARGET_STACK_PROBE"
19683 #ifdef CHECK_STACK_LIMIT
19684   if (GET_CODE (operands[1]) == CONST_INT
19685       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19686     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19687                            operands[1]));
19688   else
19689 #endif
19690     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19691                                                             operands[1])));
19693   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19694   DONE;
19697 (define_expand "builtin_setjmp_receiver"
19698   [(label_ref (match_operand 0 "" ""))]
19699   "!TARGET_64BIT && flag_pic"
19701   if (TARGET_MACHO)
19702     {
19703       rtx xops[3];
19704       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19705       rtx label_rtx = gen_label_rtx ();
19706       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19707       xops[0] = xops[1] = picreg;
19708       xops[2] = gen_rtx_CONST (SImode,
19709                   gen_rtx_MINUS (SImode,
19710                     gen_rtx_LABEL_REF (SImode, label_rtx),
19711                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19712       ix86_expand_binary_operator (MINUS, SImode, xops);
19713     }
19714   else
19715     emit_insn (gen_set_got (pic_offset_table_rtx));
19716   DONE;
19719 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19721 (define_split
19722   [(set (match_operand 0 "register_operand" "")
19723         (match_operator 3 "promotable_binary_operator"
19724            [(match_operand 1 "register_operand" "")
19725             (match_operand 2 "aligned_operand" "")]))
19726    (clobber (reg:CC FLAGS_REG))]
19727   "! TARGET_PARTIAL_REG_STALL && reload_completed
19728    && ((GET_MODE (operands[0]) == HImode
19729         && ((!optimize_size && !TARGET_FAST_PREFIX)
19730             /* ??? next two lines just !satisfies_constraint_K (...) */
19731             || GET_CODE (operands[2]) != CONST_INT
19732             || satisfies_constraint_K (operands[2])))
19733        || (GET_MODE (operands[0]) == QImode
19734            && (TARGET_PROMOTE_QImode || optimize_size)))"
19735   [(parallel [(set (match_dup 0)
19736                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19737               (clobber (reg:CC FLAGS_REG))])]
19738   "operands[0] = gen_lowpart (SImode, operands[0]);
19739    operands[1] = gen_lowpart (SImode, operands[1]);
19740    if (GET_CODE (operands[3]) != ASHIFT)
19741      operands[2] = gen_lowpart (SImode, operands[2]);
19742    PUT_MODE (operands[3], SImode);")
19744 ; Promote the QImode tests, as i386 has encoding of the AND
19745 ; instruction with 32-bit sign-extended immediate and thus the
19746 ; instruction size is unchanged, except in the %eax case for
19747 ; which it is increased by one byte, hence the ! optimize_size.
19748 (define_split
19749   [(set (match_operand 0 "flags_reg_operand" "")
19750         (match_operator 2 "compare_operator"
19751           [(and (match_operand 3 "aligned_operand" "")
19752                 (match_operand 4 "const_int_operand" ""))
19753            (const_int 0)]))
19754    (set (match_operand 1 "register_operand" "")
19755         (and (match_dup 3) (match_dup 4)))]
19756   "! TARGET_PARTIAL_REG_STALL && reload_completed
19757    /* Ensure that the operand will remain sign-extended immediate.  */
19758    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19759    && ! optimize_size
19760    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19761        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19762   [(parallel [(set (match_dup 0)
19763                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19764                                     (const_int 0)]))
19765               (set (match_dup 1)
19766                    (and:SI (match_dup 3) (match_dup 4)))])]
19768   operands[4]
19769     = gen_int_mode (INTVAL (operands[4])
19770                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19771   operands[1] = gen_lowpart (SImode, operands[1]);
19772   operands[3] = gen_lowpart (SImode, operands[3]);
19775 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19776 ; the TEST instruction with 32-bit sign-extended immediate and thus
19777 ; the instruction size would at least double, which is not what we
19778 ; want even with ! optimize_size.
19779 (define_split
19780   [(set (match_operand 0 "flags_reg_operand" "")
19781         (match_operator 1 "compare_operator"
19782           [(and (match_operand:HI 2 "aligned_operand" "")
19783                 (match_operand:HI 3 "const_int_operand" ""))
19784            (const_int 0)]))]
19785   "! TARGET_PARTIAL_REG_STALL && reload_completed
19786    /* Ensure that the operand will remain sign-extended immediate.  */
19787    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19788    && ! TARGET_FAST_PREFIX
19789    && ! optimize_size"
19790   [(set (match_dup 0)
19791         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19792                          (const_int 0)]))]
19794   operands[3]
19795     = gen_int_mode (INTVAL (operands[3])
19796                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19797   operands[2] = gen_lowpart (SImode, operands[2]);
19800 (define_split
19801   [(set (match_operand 0 "register_operand" "")
19802         (neg (match_operand 1 "register_operand" "")))
19803    (clobber (reg:CC FLAGS_REG))]
19804   "! TARGET_PARTIAL_REG_STALL && reload_completed
19805    && (GET_MODE (operands[0]) == HImode
19806        || (GET_MODE (operands[0]) == QImode
19807            && (TARGET_PROMOTE_QImode || optimize_size)))"
19808   [(parallel [(set (match_dup 0)
19809                    (neg:SI (match_dup 1)))
19810               (clobber (reg:CC FLAGS_REG))])]
19811   "operands[0] = gen_lowpart (SImode, operands[0]);
19812    operands[1] = gen_lowpart (SImode, operands[1]);")
19814 (define_split
19815   [(set (match_operand 0 "register_operand" "")
19816         (not (match_operand 1 "register_operand" "")))]
19817   "! TARGET_PARTIAL_REG_STALL && reload_completed
19818    && (GET_MODE (operands[0]) == HImode
19819        || (GET_MODE (operands[0]) == QImode
19820            && (TARGET_PROMOTE_QImode || optimize_size)))"
19821   [(set (match_dup 0)
19822         (not:SI (match_dup 1)))]
19823   "operands[0] = gen_lowpart (SImode, operands[0]);
19824    operands[1] = gen_lowpart (SImode, operands[1]);")
19826 (define_split
19827   [(set (match_operand 0 "register_operand" "")
19828         (if_then_else (match_operator 1 "comparison_operator"
19829                                 [(reg FLAGS_REG) (const_int 0)])
19830                       (match_operand 2 "register_operand" "")
19831                       (match_operand 3 "register_operand" "")))]
19832   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19833    && (GET_MODE (operands[0]) == HImode
19834        || (GET_MODE (operands[0]) == QImode
19835            && (TARGET_PROMOTE_QImode || optimize_size)))"
19836   [(set (match_dup 0)
19837         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19838   "operands[0] = gen_lowpart (SImode, operands[0]);
19839    operands[2] = gen_lowpart (SImode, operands[2]);
19840    operands[3] = gen_lowpart (SImode, operands[3]);")
19843 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19844 ;; transform a complex memory operation into two memory to register operations.
19846 ;; Don't push memory operands
19847 (define_peephole2
19848   [(set (match_operand:SI 0 "push_operand" "")
19849         (match_operand:SI 1 "memory_operand" ""))
19850    (match_scratch:SI 2 "r")]
19851   "!optimize_size && !TARGET_PUSH_MEMORY
19852    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19853   [(set (match_dup 2) (match_dup 1))
19854    (set (match_dup 0) (match_dup 2))]
19855   "")
19857 (define_peephole2
19858   [(set (match_operand:DI 0 "push_operand" "")
19859         (match_operand:DI 1 "memory_operand" ""))
19860    (match_scratch:DI 2 "r")]
19861   "!optimize_size && !TARGET_PUSH_MEMORY
19862    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19863   [(set (match_dup 2) (match_dup 1))
19864    (set (match_dup 0) (match_dup 2))]
19865   "")
19867 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19868 ;; SImode pushes.
19869 (define_peephole2
19870   [(set (match_operand:SF 0 "push_operand" "")
19871         (match_operand:SF 1 "memory_operand" ""))
19872    (match_scratch:SF 2 "r")]
19873   "!optimize_size && !TARGET_PUSH_MEMORY
19874    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19875   [(set (match_dup 2) (match_dup 1))
19876    (set (match_dup 0) (match_dup 2))]
19877   "")
19879 (define_peephole2
19880   [(set (match_operand:HI 0 "push_operand" "")
19881         (match_operand:HI 1 "memory_operand" ""))
19882    (match_scratch:HI 2 "r")]
19883   "!optimize_size && !TARGET_PUSH_MEMORY
19884    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19885   [(set (match_dup 2) (match_dup 1))
19886    (set (match_dup 0) (match_dup 2))]
19887   "")
19889 (define_peephole2
19890   [(set (match_operand:QI 0 "push_operand" "")
19891         (match_operand:QI 1 "memory_operand" ""))
19892    (match_scratch:QI 2 "q")]
19893   "!optimize_size && !TARGET_PUSH_MEMORY
19894    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19895   [(set (match_dup 2) (match_dup 1))
19896    (set (match_dup 0) (match_dup 2))]
19897   "")
19899 ;; Don't move an immediate directly to memory when the instruction
19900 ;; gets too big.
19901 (define_peephole2
19902   [(match_scratch:SI 1 "r")
19903    (set (match_operand:SI 0 "memory_operand" "")
19904         (const_int 0))]
19905   "! optimize_size
19906    && ! TARGET_USE_MOV0
19907    && TARGET_SPLIT_LONG_MOVES
19908    && get_attr_length (insn) >= ix86_cost->large_insn
19909    && peep2_regno_dead_p (0, FLAGS_REG)"
19910   [(parallel [(set (match_dup 1) (const_int 0))
19911               (clobber (reg:CC FLAGS_REG))])
19912    (set (match_dup 0) (match_dup 1))]
19913   "")
19915 (define_peephole2
19916   [(match_scratch:HI 1 "r")
19917    (set (match_operand:HI 0 "memory_operand" "")
19918         (const_int 0))]
19919   "! optimize_size
19920    && ! TARGET_USE_MOV0
19921    && TARGET_SPLIT_LONG_MOVES
19922    && get_attr_length (insn) >= ix86_cost->large_insn
19923    && peep2_regno_dead_p (0, FLAGS_REG)"
19924   [(parallel [(set (match_dup 2) (const_int 0))
19925               (clobber (reg:CC FLAGS_REG))])
19926    (set (match_dup 0) (match_dup 1))]
19927   "operands[2] = gen_lowpart (SImode, operands[1]);")
19929 (define_peephole2
19930   [(match_scratch:QI 1 "q")
19931    (set (match_operand:QI 0 "memory_operand" "")
19932         (const_int 0))]
19933   "! optimize_size
19934    && ! TARGET_USE_MOV0
19935    && TARGET_SPLIT_LONG_MOVES
19936    && get_attr_length (insn) >= ix86_cost->large_insn
19937    && peep2_regno_dead_p (0, FLAGS_REG)"
19938   [(parallel [(set (match_dup 2) (const_int 0))
19939               (clobber (reg:CC FLAGS_REG))])
19940    (set (match_dup 0) (match_dup 1))]
19941   "operands[2] = gen_lowpart (SImode, operands[1]);")
19943 (define_peephole2
19944   [(match_scratch:SI 2 "r")
19945    (set (match_operand:SI 0 "memory_operand" "")
19946         (match_operand:SI 1 "immediate_operand" ""))]
19947   "! optimize_size
19948    && get_attr_length (insn) >= ix86_cost->large_insn
19949    && TARGET_SPLIT_LONG_MOVES"
19950   [(set (match_dup 2) (match_dup 1))
19951    (set (match_dup 0) (match_dup 2))]
19952   "")
19954 (define_peephole2
19955   [(match_scratch:HI 2 "r")
19956    (set (match_operand:HI 0 "memory_operand" "")
19957         (match_operand:HI 1 "immediate_operand" ""))]
19958   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19959   && TARGET_SPLIT_LONG_MOVES"
19960   [(set (match_dup 2) (match_dup 1))
19961    (set (match_dup 0) (match_dup 2))]
19962   "")
19964 (define_peephole2
19965   [(match_scratch:QI 2 "q")
19966    (set (match_operand:QI 0 "memory_operand" "")
19967         (match_operand:QI 1 "immediate_operand" ""))]
19968   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19969   && TARGET_SPLIT_LONG_MOVES"
19970   [(set (match_dup 2) (match_dup 1))
19971    (set (match_dup 0) (match_dup 2))]
19972   "")
19974 ;; Don't compare memory with zero, load and use a test instead.
19975 (define_peephole2
19976   [(set (match_operand 0 "flags_reg_operand" "")
19977         (match_operator 1 "compare_operator"
19978           [(match_operand:SI 2 "memory_operand" "")
19979            (const_int 0)]))
19980    (match_scratch:SI 3 "r")]
19981   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19982   [(set (match_dup 3) (match_dup 2))
19983    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19984   "")
19986 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19987 ;; Don't split NOTs with a displacement operand, because resulting XOR
19988 ;; will not be pairable anyway.
19990 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19991 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19992 ;; so this split helps here as well.
19994 ;; Note: Can't do this as a regular split because we can't get proper
19995 ;; lifetime information then.
19997 (define_peephole2
19998   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19999         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20000   "!optimize_size
20001    && peep2_regno_dead_p (0, FLAGS_REG)
20002    && ((TARGET_PENTIUM
20003         && (GET_CODE (operands[0]) != MEM
20004             || !memory_displacement_operand (operands[0], SImode)))
20005        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20006   [(parallel [(set (match_dup 0)
20007                    (xor:SI (match_dup 1) (const_int -1)))
20008               (clobber (reg:CC FLAGS_REG))])]
20009   "")
20011 (define_peephole2
20012   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20013         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20014   "!optimize_size
20015    && peep2_regno_dead_p (0, FLAGS_REG)
20016    && ((TARGET_PENTIUM
20017         && (GET_CODE (operands[0]) != MEM
20018             || !memory_displacement_operand (operands[0], HImode)))
20019        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20020   [(parallel [(set (match_dup 0)
20021                    (xor:HI (match_dup 1) (const_int -1)))
20022               (clobber (reg:CC FLAGS_REG))])]
20023   "")
20025 (define_peephole2
20026   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20027         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20028   "!optimize_size
20029    && peep2_regno_dead_p (0, FLAGS_REG)
20030    && ((TARGET_PENTIUM
20031         && (GET_CODE (operands[0]) != MEM
20032             || !memory_displacement_operand (operands[0], QImode)))
20033        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20034   [(parallel [(set (match_dup 0)
20035                    (xor:QI (match_dup 1) (const_int -1)))
20036               (clobber (reg:CC FLAGS_REG))])]
20037   "")
20039 ;; Non pairable "test imm, reg" instructions can be translated to
20040 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20041 ;; byte opcode instead of two, have a short form for byte operands),
20042 ;; so do it for other CPUs as well.  Given that the value was dead,
20043 ;; this should not create any new dependencies.  Pass on the sub-word
20044 ;; versions if we're concerned about partial register stalls.
20046 (define_peephole2
20047   [(set (match_operand 0 "flags_reg_operand" "")
20048         (match_operator 1 "compare_operator"
20049           [(and:SI (match_operand:SI 2 "register_operand" "")
20050                    (match_operand:SI 3 "immediate_operand" ""))
20051            (const_int 0)]))]
20052   "ix86_match_ccmode (insn, CCNOmode)
20053    && (true_regnum (operands[2]) != 0
20054        || satisfies_constraint_K (operands[3]))
20055    && peep2_reg_dead_p (1, operands[2])"
20056   [(parallel
20057      [(set (match_dup 0)
20058            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20059                             (const_int 0)]))
20060       (set (match_dup 2)
20061            (and:SI (match_dup 2) (match_dup 3)))])]
20062   "")
20064 ;; We don't need to handle HImode case, because it will be promoted to SImode
20065 ;; on ! TARGET_PARTIAL_REG_STALL
20067 (define_peephole2
20068   [(set (match_operand 0 "flags_reg_operand" "")
20069         (match_operator 1 "compare_operator"
20070           [(and:QI (match_operand:QI 2 "register_operand" "")
20071                    (match_operand:QI 3 "immediate_operand" ""))
20072            (const_int 0)]))]
20073   "! TARGET_PARTIAL_REG_STALL
20074    && ix86_match_ccmode (insn, CCNOmode)
20075    && true_regnum (operands[2]) != 0
20076    && peep2_reg_dead_p (1, operands[2])"
20077   [(parallel
20078      [(set (match_dup 0)
20079            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20080                             (const_int 0)]))
20081       (set (match_dup 2)
20082            (and:QI (match_dup 2) (match_dup 3)))])]
20083   "")
20085 (define_peephole2
20086   [(set (match_operand 0 "flags_reg_operand" "")
20087         (match_operator 1 "compare_operator"
20088           [(and:SI
20089              (zero_extract:SI
20090                (match_operand 2 "ext_register_operand" "")
20091                (const_int 8)
20092                (const_int 8))
20093              (match_operand 3 "const_int_operand" ""))
20094            (const_int 0)]))]
20095   "! TARGET_PARTIAL_REG_STALL
20096    && ix86_match_ccmode (insn, CCNOmode)
20097    && true_regnum (operands[2]) != 0
20098    && peep2_reg_dead_p (1, operands[2])"
20099   [(parallel [(set (match_dup 0)
20100                    (match_op_dup 1
20101                      [(and:SI
20102                         (zero_extract:SI
20103                           (match_dup 2)
20104                           (const_int 8)
20105                           (const_int 8))
20106                         (match_dup 3))
20107                       (const_int 0)]))
20108               (set (zero_extract:SI (match_dup 2)
20109                                     (const_int 8)
20110                                     (const_int 8))
20111                    (and:SI
20112                      (zero_extract:SI
20113                        (match_dup 2)
20114                        (const_int 8)
20115                        (const_int 8))
20116                      (match_dup 3)))])]
20117   "")
20119 ;; Don't do logical operations with memory inputs.
20120 (define_peephole2
20121   [(match_scratch:SI 2 "r")
20122    (parallel [(set (match_operand:SI 0 "register_operand" "")
20123                    (match_operator:SI 3 "arith_or_logical_operator"
20124                      [(match_dup 0)
20125                       (match_operand:SI 1 "memory_operand" "")]))
20126               (clobber (reg:CC FLAGS_REG))])]
20127   "! optimize_size && ! TARGET_READ_MODIFY"
20128   [(set (match_dup 2) (match_dup 1))
20129    (parallel [(set (match_dup 0)
20130                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20131               (clobber (reg:CC FLAGS_REG))])]
20132   "")
20134 (define_peephole2
20135   [(match_scratch:SI 2 "r")
20136    (parallel [(set (match_operand:SI 0 "register_operand" "")
20137                    (match_operator:SI 3 "arith_or_logical_operator"
20138                      [(match_operand:SI 1 "memory_operand" "")
20139                       (match_dup 0)]))
20140               (clobber (reg:CC FLAGS_REG))])]
20141   "! optimize_size && ! TARGET_READ_MODIFY"
20142   [(set (match_dup 2) (match_dup 1))
20143    (parallel [(set (match_dup 0)
20144                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20145               (clobber (reg:CC FLAGS_REG))])]
20146   "")
20148 ; Don't do logical operations with memory outputs
20150 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20151 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20152 ; the same decoder scheduling characteristics as the original.
20154 (define_peephole2
20155   [(match_scratch:SI 2 "r")
20156    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20157                    (match_operator:SI 3 "arith_or_logical_operator"
20158                      [(match_dup 0)
20159                       (match_operand:SI 1 "nonmemory_operand" "")]))
20160               (clobber (reg:CC FLAGS_REG))])]
20161   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20162   [(set (match_dup 2) (match_dup 0))
20163    (parallel [(set (match_dup 2)
20164                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20165               (clobber (reg:CC FLAGS_REG))])
20166    (set (match_dup 0) (match_dup 2))]
20167   "")
20169 (define_peephole2
20170   [(match_scratch:SI 2 "r")
20171    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20172                    (match_operator:SI 3 "arith_or_logical_operator"
20173                      [(match_operand:SI 1 "nonmemory_operand" "")
20174                       (match_dup 0)]))
20175               (clobber (reg:CC FLAGS_REG))])]
20176   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20177   [(set (match_dup 2) (match_dup 0))
20178    (parallel [(set (match_dup 2)
20179                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20180               (clobber (reg:CC FLAGS_REG))])
20181    (set (match_dup 0) (match_dup 2))]
20182   "")
20184 ;; Attempt to always use XOR for zeroing registers.
20185 (define_peephole2
20186   [(set (match_operand 0 "register_operand" "")
20187         (match_operand 1 "const0_operand" ""))]
20188   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20189    && (! TARGET_USE_MOV0 || optimize_size)
20190    && GENERAL_REG_P (operands[0])
20191    && peep2_regno_dead_p (0, FLAGS_REG)"
20192   [(parallel [(set (match_dup 0) (const_int 0))
20193               (clobber (reg:CC FLAGS_REG))])]
20195   operands[0] = gen_lowpart (word_mode, operands[0]);
20198 (define_peephole2
20199   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20200         (const_int 0))]
20201   "(GET_MODE (operands[0]) == QImode
20202     || GET_MODE (operands[0]) == HImode)
20203    && (! TARGET_USE_MOV0 || optimize_size)
20204    && peep2_regno_dead_p (0, FLAGS_REG)"
20205   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20206               (clobber (reg:CC FLAGS_REG))])])
20208 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20209 (define_peephole2
20210   [(set (match_operand 0 "register_operand" "")
20211         (const_int -1))]
20212   "(GET_MODE (operands[0]) == HImode
20213     || GET_MODE (operands[0]) == SImode
20214     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20215    && (optimize_size || TARGET_PENTIUM)
20216    && peep2_regno_dead_p (0, FLAGS_REG)"
20217   [(parallel [(set (match_dup 0) (const_int -1))
20218               (clobber (reg:CC FLAGS_REG))])]
20219   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20220                               operands[0]);")
20222 ;; Attempt to convert simple leas to adds. These can be created by
20223 ;; move expanders.
20224 (define_peephole2
20225   [(set (match_operand:SI 0 "register_operand" "")
20226         (plus:SI (match_dup 0)
20227                  (match_operand:SI 1 "nonmemory_operand" "")))]
20228   "peep2_regno_dead_p (0, FLAGS_REG)"
20229   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20230               (clobber (reg:CC FLAGS_REG))])]
20231   "")
20233 (define_peephole2
20234   [(set (match_operand:SI 0 "register_operand" "")
20235         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20236                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20237   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20238   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20239               (clobber (reg:CC FLAGS_REG))])]
20240   "operands[2] = gen_lowpart (SImode, operands[2]);")
20242 (define_peephole2
20243   [(set (match_operand:DI 0 "register_operand" "")
20244         (plus:DI (match_dup 0)
20245                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20246   "peep2_regno_dead_p (0, FLAGS_REG)"
20247   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20248               (clobber (reg:CC FLAGS_REG))])]
20249   "")
20251 (define_peephole2
20252   [(set (match_operand:SI 0 "register_operand" "")
20253         (mult:SI (match_dup 0)
20254                  (match_operand:SI 1 "const_int_operand" "")))]
20255   "exact_log2 (INTVAL (operands[1])) >= 0
20256    && peep2_regno_dead_p (0, FLAGS_REG)"
20257   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20258               (clobber (reg:CC FLAGS_REG))])]
20259   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20261 (define_peephole2
20262   [(set (match_operand:DI 0 "register_operand" "")
20263         (mult:DI (match_dup 0)
20264                  (match_operand:DI 1 "const_int_operand" "")))]
20265   "exact_log2 (INTVAL (operands[1])) >= 0
20266    && peep2_regno_dead_p (0, FLAGS_REG)"
20267   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20268               (clobber (reg:CC FLAGS_REG))])]
20269   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20271 (define_peephole2
20272   [(set (match_operand:SI 0 "register_operand" "")
20273         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20274                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20275   "exact_log2 (INTVAL (operands[2])) >= 0
20276    && REGNO (operands[0]) == REGNO (operands[1])
20277    && peep2_regno_dead_p (0, FLAGS_REG)"
20278   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20279               (clobber (reg:CC FLAGS_REG))])]
20280   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20282 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20283 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20284 ;; many CPUs it is also faster, since special hardware to avoid esp
20285 ;; dependencies is present.
20287 ;; While some of these conversions may be done using splitters, we use peepholes
20288 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20290 ;; Convert prologue esp subtractions to push.
20291 ;; We need register to push.  In order to keep verify_flow_info happy we have
20292 ;; two choices
20293 ;; - use scratch and clobber it in order to avoid dependencies
20294 ;; - use already live register
20295 ;; We can't use the second way right now, since there is no reliable way how to
20296 ;; verify that given register is live.  First choice will also most likely in
20297 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20298 ;; call clobbered registers are dead.  We may want to use base pointer as an
20299 ;; alternative when no register is available later.
20301 (define_peephole2
20302   [(match_scratch:SI 0 "r")
20303    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20304               (clobber (reg:CC FLAGS_REG))
20305               (clobber (mem:BLK (scratch)))])]
20306   "optimize_size || !TARGET_SUB_ESP_4"
20307   [(clobber (match_dup 0))
20308    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20309               (clobber (mem:BLK (scratch)))])])
20311 (define_peephole2
20312   [(match_scratch:SI 0 "r")
20313    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20314               (clobber (reg:CC FLAGS_REG))
20315               (clobber (mem:BLK (scratch)))])]
20316   "optimize_size || !TARGET_SUB_ESP_8"
20317   [(clobber (match_dup 0))
20318    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20319    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20320               (clobber (mem:BLK (scratch)))])])
20322 ;; Convert esp subtractions to push.
20323 (define_peephole2
20324   [(match_scratch:SI 0 "r")
20325    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20326               (clobber (reg:CC FLAGS_REG))])]
20327   "optimize_size || !TARGET_SUB_ESP_4"
20328   [(clobber (match_dup 0))
20329    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20331 (define_peephole2
20332   [(match_scratch:SI 0 "r")
20333    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20334               (clobber (reg:CC FLAGS_REG))])]
20335   "optimize_size || !TARGET_SUB_ESP_8"
20336   [(clobber (match_dup 0))
20337    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20338    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20340 ;; Convert epilogue deallocator to pop.
20341 (define_peephole2
20342   [(match_scratch:SI 0 "r")
20343    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20344               (clobber (reg:CC FLAGS_REG))
20345               (clobber (mem:BLK (scratch)))])]
20346   "optimize_size || !TARGET_ADD_ESP_4"
20347   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20348               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20349               (clobber (mem:BLK (scratch)))])]
20350   "")
20352 ;; Two pops case is tricky, since pop causes dependency on destination register.
20353 ;; We use two registers if available.
20354 (define_peephole2
20355   [(match_scratch:SI 0 "r")
20356    (match_scratch:SI 1 "r")
20357    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20358               (clobber (reg:CC FLAGS_REG))
20359               (clobber (mem:BLK (scratch)))])]
20360   "optimize_size || !TARGET_ADD_ESP_8"
20361   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20362               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20363               (clobber (mem:BLK (scratch)))])
20364    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20365               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20366   "")
20368 (define_peephole2
20369   [(match_scratch:SI 0 "r")
20370    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20371               (clobber (reg:CC FLAGS_REG))
20372               (clobber (mem:BLK (scratch)))])]
20373   "optimize_size"
20374   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20375               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20376               (clobber (mem:BLK (scratch)))])
20377    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20378               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20379   "")
20381 ;; Convert esp additions to pop.
20382 (define_peephole2
20383   [(match_scratch:SI 0 "r")
20384    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20385               (clobber (reg:CC FLAGS_REG))])]
20386   ""
20387   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20388               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20389   "")
20391 ;; Two pops case is tricky, since pop causes dependency on destination register.
20392 ;; We use two registers if available.
20393 (define_peephole2
20394   [(match_scratch:SI 0 "r")
20395    (match_scratch:SI 1 "r")
20396    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20397               (clobber (reg:CC FLAGS_REG))])]
20398   ""
20399   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20400               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20401    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20402               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20403   "")
20405 (define_peephole2
20406   [(match_scratch:SI 0 "r")
20407    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20408               (clobber (reg:CC FLAGS_REG))])]
20409   "optimize_size"
20410   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20411               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20412    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20414   "")
20416 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20417 ;; required and register dies.  Similarly for 128 to plus -128.
20418 (define_peephole2
20419   [(set (match_operand 0 "flags_reg_operand" "")
20420         (match_operator 1 "compare_operator"
20421           [(match_operand 2 "register_operand" "")
20422            (match_operand 3 "const_int_operand" "")]))]
20423   "(INTVAL (operands[3]) == -1
20424     || INTVAL (operands[3]) == 1
20425     || INTVAL (operands[3]) == 128)
20426    && ix86_match_ccmode (insn, CCGCmode)
20427    && peep2_reg_dead_p (1, operands[2])"
20428   [(parallel [(set (match_dup 0)
20429                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20430               (clobber (match_dup 2))])]
20431   "")
20433 (define_peephole2
20434   [(match_scratch:DI 0 "r")
20435    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20436               (clobber (reg:CC FLAGS_REG))
20437               (clobber (mem:BLK (scratch)))])]
20438   "optimize_size || !TARGET_SUB_ESP_4"
20439   [(clobber (match_dup 0))
20440    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20441               (clobber (mem:BLK (scratch)))])])
20443 (define_peephole2
20444   [(match_scratch:DI 0 "r")
20445    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20446               (clobber (reg:CC FLAGS_REG))
20447               (clobber (mem:BLK (scratch)))])]
20448   "optimize_size || !TARGET_SUB_ESP_8"
20449   [(clobber (match_dup 0))
20450    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20451    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20452               (clobber (mem:BLK (scratch)))])])
20454 ;; Convert esp subtractions to push.
20455 (define_peephole2
20456   [(match_scratch:DI 0 "r")
20457    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20458               (clobber (reg:CC FLAGS_REG))])]
20459   "optimize_size || !TARGET_SUB_ESP_4"
20460   [(clobber (match_dup 0))
20461    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20463 (define_peephole2
20464   [(match_scratch:DI 0 "r")
20465    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20466               (clobber (reg:CC FLAGS_REG))])]
20467   "optimize_size || !TARGET_SUB_ESP_8"
20468   [(clobber (match_dup 0))
20469    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20470    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20472 ;; Convert epilogue deallocator to pop.
20473 (define_peephole2
20474   [(match_scratch:DI 0 "r")
20475    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20476               (clobber (reg:CC FLAGS_REG))
20477               (clobber (mem:BLK (scratch)))])]
20478   "optimize_size || !TARGET_ADD_ESP_4"
20479   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20480               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20481               (clobber (mem:BLK (scratch)))])]
20482   "")
20484 ;; Two pops case is tricky, since pop causes dependency on destination register.
20485 ;; We use two registers if available.
20486 (define_peephole2
20487   [(match_scratch:DI 0 "r")
20488    (match_scratch:DI 1 "r")
20489    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20490               (clobber (reg:CC FLAGS_REG))
20491               (clobber (mem:BLK (scratch)))])]
20492   "optimize_size || !TARGET_ADD_ESP_8"
20493   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20494               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20495               (clobber (mem:BLK (scratch)))])
20496    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20497               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20498   "")
20500 (define_peephole2
20501   [(match_scratch:DI 0 "r")
20502    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20503               (clobber (reg:CC FLAGS_REG))
20504               (clobber (mem:BLK (scratch)))])]
20505   "optimize_size"
20506   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20507               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20508               (clobber (mem:BLK (scratch)))])
20509    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20510               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20511   "")
20513 ;; Convert esp additions to pop.
20514 (define_peephole2
20515   [(match_scratch:DI 0 "r")
20516    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20517               (clobber (reg:CC FLAGS_REG))])]
20518   ""
20519   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20520               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20521   "")
20523 ;; Two pops case is tricky, since pop causes dependency on destination register.
20524 ;; We use two registers if available.
20525 (define_peephole2
20526   [(match_scratch:DI 0 "r")
20527    (match_scratch:DI 1 "r")
20528    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20529               (clobber (reg:CC FLAGS_REG))])]
20530   ""
20531   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20532               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20533    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20534               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20535   "")
20537 (define_peephole2
20538   [(match_scratch:DI 0 "r")
20539    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20540               (clobber (reg:CC FLAGS_REG))])]
20541   "optimize_size"
20542   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20543               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20544    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20546   "")
20548 ;; Convert imul by three, five and nine into lea
20549 (define_peephole2
20550   [(parallel
20551     [(set (match_operand:SI 0 "register_operand" "")
20552           (mult:SI (match_operand:SI 1 "register_operand" "")
20553                    (match_operand:SI 2 "const_int_operand" "")))
20554      (clobber (reg:CC FLAGS_REG))])]
20555   "INTVAL (operands[2]) == 3
20556    || INTVAL (operands[2]) == 5
20557    || INTVAL (operands[2]) == 9"
20558   [(set (match_dup 0)
20559         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20560                  (match_dup 1)))]
20561   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20563 (define_peephole2
20564   [(parallel
20565     [(set (match_operand:SI 0 "register_operand" "")
20566           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20567                    (match_operand:SI 2 "const_int_operand" "")))
20568      (clobber (reg:CC FLAGS_REG))])]
20569   "!optimize_size
20570    && (INTVAL (operands[2]) == 3
20571        || INTVAL (operands[2]) == 5
20572        || INTVAL (operands[2]) == 9)"
20573   [(set (match_dup 0) (match_dup 1))
20574    (set (match_dup 0)
20575         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20576                  (match_dup 0)))]
20577   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20579 (define_peephole2
20580   [(parallel
20581     [(set (match_operand:DI 0 "register_operand" "")
20582           (mult:DI (match_operand:DI 1 "register_operand" "")
20583                    (match_operand:DI 2 "const_int_operand" "")))
20584      (clobber (reg:CC FLAGS_REG))])]
20585   "TARGET_64BIT
20586    && (INTVAL (operands[2]) == 3
20587        || INTVAL (operands[2]) == 5
20588        || INTVAL (operands[2]) == 9)"
20589   [(set (match_dup 0)
20590         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20591                  (match_dup 1)))]
20592   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20594 (define_peephole2
20595   [(parallel
20596     [(set (match_operand:DI 0 "register_operand" "")
20597           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20598                    (match_operand:DI 2 "const_int_operand" "")))
20599      (clobber (reg:CC FLAGS_REG))])]
20600   "TARGET_64BIT
20601    && !optimize_size
20602    && (INTVAL (operands[2]) == 3
20603        || INTVAL (operands[2]) == 5
20604        || INTVAL (operands[2]) == 9)"
20605   [(set (match_dup 0) (match_dup 1))
20606    (set (match_dup 0)
20607         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20608                  (match_dup 0)))]
20609   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20611 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20612 ;; imul $32bit_imm, reg, reg is direct decoded.
20613 (define_peephole2
20614   [(match_scratch:DI 3 "r")
20615    (parallel [(set (match_operand:DI 0 "register_operand" "")
20616                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20617                             (match_operand:DI 2 "immediate_operand" "")))
20618               (clobber (reg:CC FLAGS_REG))])]
20619   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20620    && !satisfies_constraint_K (operands[2])"
20621   [(set (match_dup 3) (match_dup 1))
20622    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20623               (clobber (reg:CC FLAGS_REG))])]
20626 (define_peephole2
20627   [(match_scratch:SI 3 "r")
20628    (parallel [(set (match_operand:SI 0 "register_operand" "")
20629                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20630                             (match_operand:SI 2 "immediate_operand" "")))
20631               (clobber (reg:CC FLAGS_REG))])]
20632   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20633    && !satisfies_constraint_K (operands[2])"
20634   [(set (match_dup 3) (match_dup 1))
20635    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20636               (clobber (reg:CC FLAGS_REG))])]
20639 (define_peephole2
20640   [(match_scratch:SI 3 "r")
20641    (parallel [(set (match_operand:DI 0 "register_operand" "")
20642                    (zero_extend:DI
20643                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20644                               (match_operand:SI 2 "immediate_operand" ""))))
20645               (clobber (reg:CC FLAGS_REG))])]
20646   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20647    && !satisfies_constraint_K (operands[2])"
20648   [(set (match_dup 3) (match_dup 1))
20649    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20650               (clobber (reg:CC FLAGS_REG))])]
20653 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20654 ;; Convert it into imul reg, reg
20655 ;; It would be better to force assembler to encode instruction using long
20656 ;; immediate, but there is apparently no way to do so.
20657 (define_peephole2
20658   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20659                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20660                             (match_operand:DI 2 "const_int_operand" "")))
20661               (clobber (reg:CC FLAGS_REG))])
20662    (match_scratch:DI 3 "r")]
20663   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20664    && satisfies_constraint_K (operands[2])"
20665   [(set (match_dup 3) (match_dup 2))
20666    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20667               (clobber (reg:CC FLAGS_REG))])]
20669   if (!rtx_equal_p (operands[0], operands[1]))
20670     emit_move_insn (operands[0], operands[1]);
20673 (define_peephole2
20674   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20675                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20676                             (match_operand:SI 2 "const_int_operand" "")))
20677               (clobber (reg:CC FLAGS_REG))])
20678    (match_scratch:SI 3 "r")]
20679   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20680    && satisfies_constraint_K (operands[2])"
20681   [(set (match_dup 3) (match_dup 2))
20682    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20683               (clobber (reg:CC FLAGS_REG))])]
20685   if (!rtx_equal_p (operands[0], operands[1]))
20686     emit_move_insn (operands[0], operands[1]);
20689 (define_peephole2
20690   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20691                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20692                             (match_operand:HI 2 "immediate_operand" "")))
20693               (clobber (reg:CC FLAGS_REG))])
20694    (match_scratch:HI 3 "r")]
20695   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20696   [(set (match_dup 3) (match_dup 2))
20697    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20698               (clobber (reg:CC FLAGS_REG))])]
20700   if (!rtx_equal_p (operands[0], operands[1]))
20701     emit_move_insn (operands[0], operands[1]);
20704 ;; After splitting up read-modify operations, array accesses with memory
20705 ;; operands might end up in form:
20706 ;;  sall    $2, %eax
20707 ;;  movl    4(%esp), %edx
20708 ;;  addl    %edx, %eax
20709 ;; instead of pre-splitting:
20710 ;;  sall    $2, %eax
20711 ;;  addl    4(%esp), %eax
20712 ;; Turn it into:
20713 ;;  movl    4(%esp), %edx
20714 ;;  leal    (%edx,%eax,4), %eax
20716 (define_peephole2
20717   [(parallel [(set (match_operand 0 "register_operand" "")
20718                    (ashift (match_operand 1 "register_operand" "")
20719                            (match_operand 2 "const_int_operand" "")))
20720                (clobber (reg:CC FLAGS_REG))])
20721    (set (match_operand 3 "register_operand")
20722         (match_operand 4 "x86_64_general_operand" ""))
20723    (parallel [(set (match_operand 5 "register_operand" "")
20724                    (plus (match_operand 6 "register_operand" "")
20725                          (match_operand 7 "register_operand" "")))
20726                    (clobber (reg:CC FLAGS_REG))])]
20727   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20728    /* Validate MODE for lea.  */
20729    && ((!TARGET_PARTIAL_REG_STALL
20730         && (GET_MODE (operands[0]) == QImode
20731             || GET_MODE (operands[0]) == HImode))
20732        || GET_MODE (operands[0]) == SImode
20733        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20734    /* We reorder load and the shift.  */
20735    && !rtx_equal_p (operands[1], operands[3])
20736    && !reg_overlap_mentioned_p (operands[0], operands[4])
20737    /* Last PLUS must consist of operand 0 and 3.  */
20738    && !rtx_equal_p (operands[0], operands[3])
20739    && (rtx_equal_p (operands[3], operands[6])
20740        || rtx_equal_p (operands[3], operands[7]))
20741    && (rtx_equal_p (operands[0], operands[6])
20742        || rtx_equal_p (operands[0], operands[7]))
20743    /* The intermediate operand 0 must die or be same as output.  */
20744    && (rtx_equal_p (operands[0], operands[5])
20745        || peep2_reg_dead_p (3, operands[0]))"
20746   [(set (match_dup 3) (match_dup 4))
20747    (set (match_dup 0) (match_dup 1))]
20749   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20750   int scale = 1 << INTVAL (operands[2]);
20751   rtx index = gen_lowpart (Pmode, operands[1]);
20752   rtx base = gen_lowpart (Pmode, operands[3]);
20753   rtx dest = gen_lowpart (mode, operands[5]);
20755   operands[1] = gen_rtx_PLUS (Pmode, base,
20756                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20757   if (mode != Pmode)
20758     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20759   operands[0] = dest;
20762 ;; Call-value patterns last so that the wildcard operand does not
20763 ;; disrupt insn-recog's switch tables.
20765 (define_insn "*call_value_pop_0"
20766   [(set (match_operand 0 "" "")
20767         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20768               (match_operand:SI 2 "" "")))
20769    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20770                             (match_operand:SI 3 "immediate_operand" "")))]
20771   "!TARGET_64BIT"
20773   if (SIBLING_CALL_P (insn))
20774     return "jmp\t%P1";
20775   else
20776     return "call\t%P1";
20778   [(set_attr "type" "callv")])
20780 (define_insn "*call_value_pop_1"
20781   [(set (match_operand 0 "" "")
20782         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20783               (match_operand:SI 2 "" "")))
20784    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20785                             (match_operand:SI 3 "immediate_operand" "i")))]
20786   "!TARGET_64BIT"
20788   if (constant_call_address_operand (operands[1], Pmode))
20789     {
20790       if (SIBLING_CALL_P (insn))
20791         return "jmp\t%P1";
20792       else
20793         return "call\t%P1";
20794     }
20795   if (SIBLING_CALL_P (insn))
20796     return "jmp\t%A1";
20797   else
20798     return "call\t%A1";
20800   [(set_attr "type" "callv")])
20802 (define_insn "*call_value_0"
20803   [(set (match_operand 0 "" "")
20804         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20805               (match_operand:SI 2 "" "")))]
20806   "!TARGET_64BIT"
20808   if (SIBLING_CALL_P (insn))
20809     return "jmp\t%P1";
20810   else
20811     return "call\t%P1";
20813   [(set_attr "type" "callv")])
20815 (define_insn "*call_value_0_rex64"
20816   [(set (match_operand 0 "" "")
20817         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20818               (match_operand:DI 2 "const_int_operand" "")))]
20819   "TARGET_64BIT"
20821   if (SIBLING_CALL_P (insn))
20822     return "jmp\t%P1";
20823   else
20824     return "call\t%P1";
20826   [(set_attr "type" "callv")])
20828 (define_insn "*call_value_1"
20829   [(set (match_operand 0 "" "")
20830         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20831               (match_operand:SI 2 "" "")))]
20832   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20834   if (constant_call_address_operand (operands[1], Pmode))
20835     return "call\t%P1";
20836   return "call\t%A1";
20838   [(set_attr "type" "callv")])
20840 (define_insn "*sibcall_value_1"
20841   [(set (match_operand 0 "" "")
20842         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20843               (match_operand:SI 2 "" "")))]
20844   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20846   if (constant_call_address_operand (operands[1], Pmode))
20847     return "jmp\t%P1";
20848   return "jmp\t%A1";
20850   [(set_attr "type" "callv")])
20852 (define_insn "*call_value_1_rex64"
20853   [(set (match_operand 0 "" "")
20854         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20855               (match_operand:DI 2 "" "")))]
20856   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20858   if (constant_call_address_operand (operands[1], Pmode))
20859     return "call\t%P1";
20860   return "call\t%A1";
20862   [(set_attr "type" "callv")])
20864 (define_insn "*sibcall_value_1_rex64"
20865   [(set (match_operand 0 "" "")
20866         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20867               (match_operand:DI 2 "" "")))]
20868   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20869   "jmp\t%P1"
20870   [(set_attr "type" "callv")])
20872 (define_insn "*sibcall_value_1_rex64_v"
20873   [(set (match_operand 0 "" "")
20874         (call (mem:QI (reg:DI R11_REG))
20875               (match_operand:DI 1 "" "")))]
20876   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20877   "jmp\t*%%r11"
20878   [(set_attr "type" "callv")])
20880 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20881 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20882 ;; caught for use by garbage collectors and the like.  Using an insn that
20883 ;; maps to SIGILL makes it more likely the program will rightfully die.
20884 ;; Keeping with tradition, "6" is in honor of #UD.
20885 (define_insn "trap"
20886   [(trap_if (const_int 1) (const_int 6))]
20887   ""
20888   { return ASM_SHORT "0x0b0f"; }
20889   [(set_attr "length" "2")])
20891 (define_expand "sse_prologue_save"
20892   [(parallel [(set (match_operand:BLK 0 "" "")
20893                    (unspec:BLK [(reg:DI 22)
20894                                 (reg:DI 23)
20895                                 (reg:DI 24)
20896                                 (reg:DI 25)
20897                                 (reg:DI 26)
20898                                 (reg:DI 27)
20899                                 (reg:DI 28)
20900                                 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20901               (use (match_operand:DI 1 "register_operand" ""))
20902               (use (match_operand:DI 2 "immediate_operand" ""))
20903               (use (label_ref:DI (match_operand 3 "" "")))])]
20904   "TARGET_64BIT"
20905   "")
20907 (define_insn "*sse_prologue_save_insn"
20908   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20909                           (match_operand:DI 4 "const_int_operand" "n")))
20910         (unspec:BLK [(reg:DI 22)
20911                      (reg:DI 23)
20912                      (reg:DI 24)
20913                      (reg:DI 25)
20914                      (reg:DI 26)
20915                      (reg:DI 27)
20916                      (reg:DI 28)
20917                      (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20918    (use (match_operand:DI 1 "register_operand" "r"))
20919    (use (match_operand:DI 2 "const_int_operand" "i"))
20920    (use (label_ref:DI (match_operand 3 "" "X")))]
20921   "TARGET_64BIT
20922    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20923    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20924   "*
20926   int i;
20927   operands[0] = gen_rtx_MEM (Pmode,
20928                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20929   output_asm_insn (\"jmp\\t%A1\", operands);
20930   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20931     {
20932       operands[4] = adjust_address (operands[0], DImode, i*16);
20933       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20934       PUT_MODE (operands[4], TImode);
20935       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20936         output_asm_insn (\"rex\", operands);
20937       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20938     }
20939   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20940                              CODE_LABEL_NUMBER (operands[3]));
20941   RET;
20943   "
20944   [(set_attr "type" "other")
20945    (set_attr "length_immediate" "0")
20946    (set_attr "length_address" "0")
20947    (set_attr "length" "135")
20948    (set_attr "memory" "store")
20949    (set_attr "modrm" "0")
20950    (set_attr "mode" "DI")])
20952 (define_expand "prefetch"
20953   [(prefetch (match_operand 0 "address_operand" "")
20954              (match_operand:SI 1 "const_int_operand" "")
20955              (match_operand:SI 2 "const_int_operand" ""))]
20956   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20958   int rw = INTVAL (operands[1]);
20959   int locality = INTVAL (operands[2]);
20961   gcc_assert (rw == 0 || rw == 1);
20962   gcc_assert (locality >= 0 && locality <= 3);
20963   gcc_assert (GET_MODE (operands[0]) == Pmode
20964               || GET_MODE (operands[0]) == VOIDmode);
20966   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20967      supported by SSE counterpart or the SSE prefetch is not available
20968      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20969      of locality.  */
20970   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20971     operands[2] = GEN_INT (3);
20972   else
20973     operands[1] = const0_rtx;
20976 (define_insn "*prefetch_sse"
20977   [(prefetch (match_operand:SI 0 "address_operand" "p")
20978              (const_int 0)
20979              (match_operand:SI 1 "const_int_operand" ""))]
20980   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20982   static const char * const patterns[4] = {
20983    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20984   };
20986   int locality = INTVAL (operands[1]);
20987   gcc_assert (locality >= 0 && locality <= 3);
20989   return patterns[locality];
20991   [(set_attr "type" "sse")
20992    (set_attr "memory" "none")])
20994 (define_insn "*prefetch_sse_rex"
20995   [(prefetch (match_operand:DI 0 "address_operand" "p")
20996              (const_int 0)
20997              (match_operand:SI 1 "const_int_operand" ""))]
20998   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21000   static const char * const patterns[4] = {
21001    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21002   };
21004   int locality = INTVAL (operands[1]);
21005   gcc_assert (locality >= 0 && locality <= 3);
21007   return patterns[locality];
21009   [(set_attr "type" "sse")
21010    (set_attr "memory" "none")])
21012 (define_insn "*prefetch_3dnow"
21013   [(prefetch (match_operand:SI 0 "address_operand" "p")
21014              (match_operand:SI 1 "const_int_operand" "n")
21015              (const_int 3))]
21016   "TARGET_3DNOW && !TARGET_64BIT"
21018   if (INTVAL (operands[1]) == 0)
21019     return "prefetch\t%a0";
21020   else
21021     return "prefetchw\t%a0";
21023   [(set_attr "type" "mmx")
21024    (set_attr "memory" "none")])
21026 (define_insn "*prefetch_3dnow_rex"
21027   [(prefetch (match_operand:DI 0 "address_operand" "p")
21028              (match_operand:SI 1 "const_int_operand" "n")
21029              (const_int 3))]
21030   "TARGET_3DNOW && TARGET_64BIT"
21032   if (INTVAL (operands[1]) == 0)
21033     return "prefetch\t%a0";
21034   else
21035     return "prefetchw\t%a0";
21037   [(set_attr "type" "mmx")
21038    (set_attr "memory" "none")])
21040 (define_expand "stack_protect_set"
21041   [(match_operand 0 "memory_operand" "")
21042    (match_operand 1 "memory_operand" "")]
21043   ""
21045 #ifdef TARGET_THREAD_SSP_OFFSET
21046   if (TARGET_64BIT)
21047     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21048                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21049   else
21050     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21051                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21052 #else
21053   if (TARGET_64BIT)
21054     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21055   else
21056     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21057 #endif
21058   DONE;
21061 (define_insn "stack_protect_set_si"
21062   [(set (match_operand:SI 0 "memory_operand" "=m")
21063         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21064    (set (match_scratch:SI 2 "=&r") (const_int 0))
21065    (clobber (reg:CC FLAGS_REG))]
21066   ""
21067   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21068   [(set_attr "type" "multi")])
21070 (define_insn "stack_protect_set_di"
21071   [(set (match_operand:DI 0 "memory_operand" "=m")
21072         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21073    (set (match_scratch:DI 2 "=&r") (const_int 0))
21074    (clobber (reg:CC FLAGS_REG))]
21075   "TARGET_64BIT"
21076   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21077   [(set_attr "type" "multi")])
21079 (define_insn "stack_tls_protect_set_si"
21080   [(set (match_operand:SI 0 "memory_operand" "=m")
21081         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21082    (set (match_scratch:SI 2 "=&r") (const_int 0))
21083    (clobber (reg:CC FLAGS_REG))]
21084   ""
21085   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21086   [(set_attr "type" "multi")])
21088 (define_insn "stack_tls_protect_set_di"
21089   [(set (match_operand:DI 0 "memory_operand" "=m")
21090         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21091    (set (match_scratch:DI 2 "=&r") (const_int 0))
21092    (clobber (reg:CC FLAGS_REG))]
21093   "TARGET_64BIT"
21094   {
21095      /* The kernel uses a different segment register for performance reasons; a
21096         system call would not have to trash the userspace segment register,
21097         which would be expensive */
21098      if (ix86_cmodel != CM_KERNEL)
21099         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21100      else
21101         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21102   }
21103   [(set_attr "type" "multi")])
21105 (define_expand "stack_protect_test"
21106   [(match_operand 0 "memory_operand" "")
21107    (match_operand 1 "memory_operand" "")
21108    (match_operand 2 "" "")]
21109   ""
21111   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21112   ix86_compare_op0 = operands[0];
21113   ix86_compare_op1 = operands[1];
21114   ix86_compare_emitted = flags;
21116 #ifdef TARGET_THREAD_SSP_OFFSET
21117   if (TARGET_64BIT)
21118     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21119                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21120   else
21121     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21122                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21123 #else
21124   if (TARGET_64BIT)
21125     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21126   else
21127     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21128 #endif
21129   emit_jump_insn (gen_beq (operands[2]));
21130   DONE;
21133 (define_insn "stack_protect_test_si"
21134   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21135         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21136                      (match_operand:SI 2 "memory_operand" "m")]
21137                     UNSPEC_SP_TEST))
21138    (clobber (match_scratch:SI 3 "=&r"))]
21139   ""
21140   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21141   [(set_attr "type" "multi")])
21143 (define_insn "stack_protect_test_di"
21144   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21145         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21146                      (match_operand:DI 2 "memory_operand" "m")]
21147                     UNSPEC_SP_TEST))
21148    (clobber (match_scratch:DI 3 "=&r"))]
21149   "TARGET_64BIT"
21150   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21151   [(set_attr "type" "multi")])
21153 (define_insn "stack_tls_protect_test_si"
21154   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21155         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21156                      (match_operand:SI 2 "const_int_operand" "i")]
21157                     UNSPEC_SP_TLS_TEST))
21158    (clobber (match_scratch:SI 3 "=r"))]
21159   ""
21160   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21161   [(set_attr "type" "multi")])
21163 (define_insn "stack_tls_protect_test_di"
21164   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21165         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21166                      (match_operand:DI 2 "const_int_operand" "i")]
21167                     UNSPEC_SP_TLS_TEST))
21168    (clobber (match_scratch:DI 3 "=r"))]
21169   "TARGET_64BIT"
21170   {
21171      /* The kernel uses a different segment register for performance reasons; a
21172         system call would not have to trash the userspace segment register,
21173         which would be expensive */
21174      if (ix86_cmodel != CM_KERNEL)
21175         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21176      else
21177         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21178   }
21179   [(set_attr "type" "multi")])
21181 (include "mmx.md")
21182 (include "sse.md")
21183 (include "sync.md")