* expr.c (emit_block_move_via_movmem, emit_block_move_via_libcall): Add
[official-gcc.git] / gcc / config / i386 / i386.md
blob21d1c2b009235f7a473f6589fe92bcde85cf8b28
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, 2007
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
88    (UNSPEC_TRUNC_NOOP           29)
90    ; For SSE/MMX support:
91    (UNSPEC_FIX_NOTRUNC          30)
92    (UNSPEC_MASKMOV              31)
93    (UNSPEC_MOVMSK               32)
94    (UNSPEC_MOVNT                33)
95    (UNSPEC_MOVU                 34)
96    (UNSPEC_RCP                  35)
97    (UNSPEC_RSQRT                36)
98    (UNSPEC_SFENCE               37)
99    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
100    (UNSPEC_PFRCP                39)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
110    ; Generic math support
111    (UNSPEC_COPYSIGN             50)
112    (UNSPEC_IEEE_MIN             51)     ; not commutative
113    (UNSPEC_IEEE_MAX             52)     ; not commutative
115    ; x87 Floating point
116    (UNSPEC_SIN                  60)
117    (UNSPEC_COS                  61)
118    (UNSPEC_FPATAN               62)
119    (UNSPEC_FYL2X                63)
120    (UNSPEC_FYL2XP1              64)
121    (UNSPEC_FRNDINT              65)
122    (UNSPEC_FIST                 66)
123    (UNSPEC_F2XM1                67)
124    (UNSPEC_TAN                  68)
126    ; x87 Rounding
127    (UNSPEC_FRNDINT_FLOOR        70)
128    (UNSPEC_FRNDINT_CEIL         71)
129    (UNSPEC_FRNDINT_TRUNC        72)
130    (UNSPEC_FRNDINT_MASK_PM      73)
131    (UNSPEC_FIST_FLOOR           74)
132    (UNSPEC_FIST_CEIL            75)
134    ; x87 Double output FP
135    (UNSPEC_SINCOS_COS           80)
136    (UNSPEC_SINCOS_SIN           81)
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    (R10_REG                     39)
183    (R11_REG                     40)
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,
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,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,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,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")
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 ;; x87 SFmode and DFMode floating point modes
465 (define_mode_macro X87MODEF12 [SF DF])
467 ;; All integer modes handled by x87 fisttp operator.
468 (define_mode_macro X87MODEI [HI SI DI])
470 ;; All integer modes handled by integer x87 operators.
471 (define_mode_macro X87MODEI12 [HI SI])
473 ;; All SSE floating point modes
474 (define_mode_macro SSEMODEF [SF DF])
476 ;; All integer modes handled by SSE cvtts?2si* operators.
477 (define_mode_macro SSEMODEI24 [SI DI])
479 ;; SSE asm suffix for floating point modes
480 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
483 ;; Scheduling descriptions
485 (include "pentium.md")
486 (include "ppro.md")
487 (include "k6.md")
488 (include "athlon.md")
489 (include "geode.md")
492 ;; Operand and operator predicates and constraints
494 (include "predicates.md")
495 (include "constraints.md")
498 ;; Compare instructions.
500 ;; All compare insns have expanders that save the operands away without
501 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
502 ;; after the cmp) will actually emit the cmpM.
504 (define_expand "cmpti"
505   [(set (reg:CC FLAGS_REG)
506         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
507                     (match_operand:TI 1 "x86_64_general_operand" "")))]
508   "TARGET_64BIT"
510   if (MEM_P (operands[0]) && MEM_P (operands[1]))
511     operands[0] = force_reg (TImode, operands[0]);
512   ix86_compare_op0 = operands[0];
513   ix86_compare_op1 = operands[1];
514   DONE;
517 (define_expand "cmpdi"
518   [(set (reg:CC FLAGS_REG)
519         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
520                     (match_operand:DI 1 "x86_64_general_operand" "")))]
521   ""
523   if (MEM_P (operands[0]) && MEM_P (operands[1]))
524     operands[0] = force_reg (DImode, operands[0]);
525   ix86_compare_op0 = operands[0];
526   ix86_compare_op1 = operands[1];
527   DONE;
530 (define_expand "cmpsi"
531   [(set (reg:CC FLAGS_REG)
532         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
533                     (match_operand:SI 1 "general_operand" "")))]
534   ""
536   if (MEM_P (operands[0]) && MEM_P (operands[1]))
537     operands[0] = force_reg (SImode, operands[0]);
538   ix86_compare_op0 = operands[0];
539   ix86_compare_op1 = operands[1];
540   DONE;
543 (define_expand "cmphi"
544   [(set (reg:CC FLAGS_REG)
545         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
546                     (match_operand:HI 1 "general_operand" "")))]
547   ""
549   if (MEM_P (operands[0]) && MEM_P (operands[1]))
550     operands[0] = force_reg (HImode, operands[0]);
551   ix86_compare_op0 = operands[0];
552   ix86_compare_op1 = operands[1];
553   DONE;
556 (define_expand "cmpqi"
557   [(set (reg:CC FLAGS_REG)
558         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
559                     (match_operand:QI 1 "general_operand" "")))]
560   "TARGET_QIMODE_MATH"
562   if (MEM_P (operands[0]) && MEM_P (operands[1]))
563     operands[0] = force_reg (QImode, operands[0]);
564   ix86_compare_op0 = operands[0];
565   ix86_compare_op1 = operands[1];
566   DONE;
569 (define_insn "cmpdi_ccno_1_rex64"
570   [(set (reg FLAGS_REG)
571         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
572                  (match_operand:DI 1 "const0_operand" "n,n")))]
573   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
574   "@
575    test{q}\t{%0, %0|%0, %0}
576    cmp{q}\t{%1, %0|%0, %1}"
577   [(set_attr "type" "test,icmp")
578    (set_attr "length_immediate" "0,1")
579    (set_attr "mode" "DI")])
581 (define_insn "*cmpdi_minus_1_rex64"
582   [(set (reg FLAGS_REG)
583         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
584                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
585                  (const_int 0)))]
586   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
587   "cmp{q}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "DI")])
591 (define_expand "cmpdi_1_rex64"
592   [(set (reg:CC FLAGS_REG)
593         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
594                     (match_operand:DI 1 "general_operand" "")))]
595   "TARGET_64BIT"
596   "")
598 (define_insn "cmpdi_1_insn_rex64"
599   [(set (reg FLAGS_REG)
600         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
601                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
602   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
603   "cmp{q}\t{%1, %0|%0, %1}"
604   [(set_attr "type" "icmp")
605    (set_attr "mode" "DI")])
608 (define_insn "*cmpsi_ccno_1"
609   [(set (reg FLAGS_REG)
610         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
611                  (match_operand:SI 1 "const0_operand" "n,n")))]
612   "ix86_match_ccmode (insn, CCNOmode)"
613   "@
614    test{l}\t{%0, %0|%0, %0}
615    cmp{l}\t{%1, %0|%0, %1}"
616   [(set_attr "type" "test,icmp")
617    (set_attr "length_immediate" "0,1")
618    (set_attr "mode" "SI")])
620 (define_insn "*cmpsi_minus_1"
621   [(set (reg FLAGS_REG)
622         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623                            (match_operand:SI 1 "general_operand" "ri,mr"))
624                  (const_int 0)))]
625   "ix86_match_ccmode (insn, CCGOCmode)"
626   "cmp{l}\t{%1, %0|%0, %1}"
627   [(set_attr "type" "icmp")
628    (set_attr "mode" "SI")])
630 (define_expand "cmpsi_1"
631   [(set (reg:CC FLAGS_REG)
632         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
633                     (match_operand:SI 1 "general_operand" "ri,mr")))]
634   ""
635   "")
637 (define_insn "*cmpsi_1_insn"
638   [(set (reg FLAGS_REG)
639         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
640                  (match_operand:SI 1 "general_operand" "ri,mr")))]
641   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
642     && ix86_match_ccmode (insn, CCmode)"
643   "cmp{l}\t{%1, %0|%0, %1}"
644   [(set_attr "type" "icmp")
645    (set_attr "mode" "SI")])
647 (define_insn "*cmphi_ccno_1"
648   [(set (reg FLAGS_REG)
649         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
650                  (match_operand:HI 1 "const0_operand" "n,n")))]
651   "ix86_match_ccmode (insn, CCNOmode)"
652   "@
653    test{w}\t{%0, %0|%0, %0}
654    cmp{w}\t{%1, %0|%0, %1}"
655   [(set_attr "type" "test,icmp")
656    (set_attr "length_immediate" "0,1")
657    (set_attr "mode" "HI")])
659 (define_insn "*cmphi_minus_1"
660   [(set (reg FLAGS_REG)
661         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
662                            (match_operand:HI 1 "general_operand" "ri,mr"))
663                  (const_int 0)))]
664   "ix86_match_ccmode (insn, CCGOCmode)"
665   "cmp{w}\t{%1, %0|%0, %1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "HI")])
669 (define_insn "*cmphi_1"
670   [(set (reg FLAGS_REG)
671         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
672                  (match_operand:HI 1 "general_operand" "ri,mr")))]
673   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
674    && ix86_match_ccmode (insn, CCmode)"
675   "cmp{w}\t{%1, %0|%0, %1}"
676   [(set_attr "type" "icmp")
677    (set_attr "mode" "HI")])
679 (define_insn "*cmpqi_ccno_1"
680   [(set (reg FLAGS_REG)
681         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
682                  (match_operand:QI 1 "const0_operand" "n,n")))]
683   "ix86_match_ccmode (insn, CCNOmode)"
684   "@
685    test{b}\t{%0, %0|%0, %0}
686    cmp{b}\t{$0, %0|%0, 0}"
687   [(set_attr "type" "test,icmp")
688    (set_attr "length_immediate" "0,1")
689    (set_attr "mode" "QI")])
691 (define_insn "*cmpqi_1"
692   [(set (reg FLAGS_REG)
693         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
694                  (match_operand:QI 1 "general_operand" "qi,mq")))]
695   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
696     && ix86_match_ccmode (insn, CCmode)"
697   "cmp{b}\t{%1, %0|%0, %1}"
698   [(set_attr "type" "icmp")
699    (set_attr "mode" "QI")])
701 (define_insn "*cmpqi_minus_1"
702   [(set (reg FLAGS_REG)
703         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
704                            (match_operand:QI 1 "general_operand" "qi,mq"))
705                  (const_int 0)))]
706   "ix86_match_ccmode (insn, CCGOCmode)"
707   "cmp{b}\t{%1, %0|%0, %1}"
708   [(set_attr "type" "icmp")
709    (set_attr "mode" "QI")])
711 (define_insn "*cmpqi_ext_1"
712   [(set (reg FLAGS_REG)
713         (compare
714           (match_operand:QI 0 "general_operand" "Qm")
715           (subreg:QI
716             (zero_extract:SI
717               (match_operand 1 "ext_register_operand" "Q")
718               (const_int 8)
719               (const_int 8)) 0)))]
720   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721   "cmp{b}\t{%h1, %0|%0, %h1}"
722   [(set_attr "type" "icmp")
723    (set_attr "mode" "QI")])
725 (define_insn "*cmpqi_ext_1_rex64"
726   [(set (reg FLAGS_REG)
727         (compare
728           (match_operand:QI 0 "register_operand" "Q")
729           (subreg:QI
730             (zero_extract:SI
731               (match_operand 1 "ext_register_operand" "Q")
732               (const_int 8)
733               (const_int 8)) 0)))]
734   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735   "cmp{b}\t{%h1, %0|%0, %h1}"
736   [(set_attr "type" "icmp")
737    (set_attr "mode" "QI")])
739 (define_insn "*cmpqi_ext_2"
740   [(set (reg FLAGS_REG)
741         (compare
742           (subreg:QI
743             (zero_extract:SI
744               (match_operand 0 "ext_register_operand" "Q")
745               (const_int 8)
746               (const_int 8)) 0)
747           (match_operand:QI 1 "const0_operand" "n")))]
748   "ix86_match_ccmode (insn, CCNOmode)"
749   "test{b}\t%h0, %h0"
750   [(set_attr "type" "test")
751    (set_attr "length_immediate" "0")
752    (set_attr "mode" "QI")])
754 (define_expand "cmpqi_ext_3"
755   [(set (reg:CC FLAGS_REG)
756         (compare:CC
757           (subreg:QI
758             (zero_extract:SI
759               (match_operand 0 "ext_register_operand" "")
760               (const_int 8)
761               (const_int 8)) 0)
762           (match_operand:QI 1 "general_operand" "")))]
763   ""
764   "")
766 (define_insn "cmpqi_ext_3_insn"
767   [(set (reg FLAGS_REG)
768         (compare
769           (subreg:QI
770             (zero_extract:SI
771               (match_operand 0 "ext_register_operand" "Q")
772               (const_int 8)
773               (const_int 8)) 0)
774           (match_operand:QI 1 "general_operand" "Qmn")))]
775   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776   "cmp{b}\t{%1, %h0|%h0, %1}"
777   [(set_attr "type" "icmp")
778    (set_attr "mode" "QI")])
780 (define_insn "cmpqi_ext_3_insn_rex64"
781   [(set (reg FLAGS_REG)
782         (compare
783           (subreg:QI
784             (zero_extract:SI
785               (match_operand 0 "ext_register_operand" "Q")
786               (const_int 8)
787               (const_int 8)) 0)
788           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
789   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
790   "cmp{b}\t{%1, %h0|%h0, %1}"
791   [(set_attr "type" "icmp")
792    (set_attr "mode" "QI")])
794 (define_insn "*cmpqi_ext_4"
795   [(set (reg FLAGS_REG)
796         (compare
797           (subreg:QI
798             (zero_extract:SI
799               (match_operand 0 "ext_register_operand" "Q")
800               (const_int 8)
801               (const_int 8)) 0)
802           (subreg:QI
803             (zero_extract:SI
804               (match_operand 1 "ext_register_operand" "Q")
805               (const_int 8)
806               (const_int 8)) 0)))]
807   "ix86_match_ccmode (insn, CCmode)"
808   "cmp{b}\t{%h1, %h0|%h0, %h1}"
809   [(set_attr "type" "icmp")
810    (set_attr "mode" "QI")])
812 ;; These implement float point compares.
813 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
814 ;; which would allow mix and match FP modes on the compares.  Which is what
815 ;; the old patterns did, but with many more of them.
817 (define_expand "cmpxf"
818   [(set (reg:CC FLAGS_REG)
819         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
820                     (match_operand:XF 1 "nonmemory_operand" "")))]
821   "TARGET_80387"
823   ix86_compare_op0 = operands[0];
824   ix86_compare_op1 = operands[1];
825   DONE;
828 (define_expand "cmpdf"
829   [(set (reg:CC FLAGS_REG)
830         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
831                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
832   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
834   ix86_compare_op0 = operands[0];
835   ix86_compare_op1 = operands[1];
836   DONE;
839 (define_expand "cmpsf"
840   [(set (reg:CC FLAGS_REG)
841         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
842                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
843   "TARGET_80387 || TARGET_SSE_MATH"
845   ix86_compare_op0 = operands[0];
846   ix86_compare_op1 = operands[1];
847   DONE;
850 ;; FP compares, step 1:
851 ;; Set the FP condition codes.
853 ;; CCFPmode     compare with exceptions
854 ;; CCFPUmode    compare with no exceptions
856 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
857 ;; used to manage the reg stack popping would not be preserved.
859 (define_insn "*cmpfp_0"
860   [(set (match_operand:HI 0 "register_operand" "=a")
861         (unspec:HI
862           [(compare:CCFP
863              (match_operand 1 "register_operand" "f")
864              (match_operand 2 "const0_operand" "X"))]
865         UNSPEC_FNSTSW))]
866   "TARGET_80387
867    && FLOAT_MODE_P (GET_MODE (operands[1]))
868    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
869   "* return output_fp_compare (insn, operands, 0, 0);"
870   [(set_attr "type" "multi")
871    (set_attr "unit" "i387")
872    (set (attr "mode")
873      (cond [(match_operand:SF 1 "" "")
874               (const_string "SF")
875             (match_operand:DF 1 "" "")
876               (const_string "DF")
877            ]
878            (const_string "XF")))])
880 (define_insn "*cmpfp_sf"
881   [(set (match_operand:HI 0 "register_operand" "=a")
882         (unspec:HI
883           [(compare:CCFP
884              (match_operand:SF 1 "register_operand" "f")
885              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
886           UNSPEC_FNSTSW))]
887   "TARGET_80387"
888   "* return output_fp_compare (insn, operands, 0, 0);"
889   [(set_attr "type" "multi")
890    (set_attr "unit" "i387")
891    (set_attr "mode" "SF")])
893 (define_insn "*cmpfp_df"
894   [(set (match_operand:HI 0 "register_operand" "=a")
895         (unspec:HI
896           [(compare:CCFP
897              (match_operand:DF 1 "register_operand" "f")
898              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
899           UNSPEC_FNSTSW))]
900   "TARGET_80387"
901   "* return output_fp_compare (insn, operands, 0, 0);"
902   [(set_attr "type" "multi")
903    (set_attr "unit" "i387")
904    (set_attr "mode" "DF")])
906 (define_insn "*cmpfp_xf"
907   [(set (match_operand:HI 0 "register_operand" "=a")
908         (unspec:HI
909           [(compare:CCFP
910              (match_operand:XF 1 "register_operand" "f")
911              (match_operand:XF 2 "register_operand" "f"))]
912           UNSPEC_FNSTSW))]
913   "TARGET_80387"
914   "* return output_fp_compare (insn, operands, 0, 0);"
915   [(set_attr "type" "multi")
916    (set_attr "unit" "i387")
917    (set_attr "mode" "XF")])
919 (define_insn "*cmpfp_u"
920   [(set (match_operand:HI 0 "register_operand" "=a")
921         (unspec:HI
922           [(compare:CCFPU
923              (match_operand 1 "register_operand" "f")
924              (match_operand 2 "register_operand" "f"))]
925           UNSPEC_FNSTSW))]
926   "TARGET_80387
927    && FLOAT_MODE_P (GET_MODE (operands[1]))
928    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
929   "* return output_fp_compare (insn, operands, 0, 1);"
930   [(set_attr "type" "multi")
931    (set_attr "unit" "i387")
932    (set (attr "mode")
933      (cond [(match_operand:SF 1 "" "")
934               (const_string "SF")
935             (match_operand:DF 1 "" "")
936               (const_string "DF")
937            ]
938            (const_string "XF")))])
940 (define_insn "*cmpfp_<mode>"
941   [(set (match_operand:HI 0 "register_operand" "=a")
942         (unspec:HI
943           [(compare:CCFP
944              (match_operand 1 "register_operand" "f")
945              (match_operator 3 "float_operator"
946                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
947           UNSPEC_FNSTSW))]
948   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
949    && FLOAT_MODE_P (GET_MODE (operands[1]))
950    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
951   "* return output_fp_compare (insn, operands, 0, 0);"
952   [(set_attr "type" "multi")
953    (set_attr "unit" "i387")
954    (set_attr "fp_int_src" "true")
955    (set_attr "mode" "<MODE>")])
957 ;; FP compares, step 2
958 ;; Move the fpsw to ax.
960 (define_insn "x86_fnstsw_1"
961   [(set (match_operand:HI 0 "register_operand" "=a")
962         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
963   "TARGET_80387"
964   "fnstsw\t%0"
965   [(set_attr "length" "2")
966    (set_attr "mode" "SI")
967    (set_attr "unit" "i387")])
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
972 (define_insn "x86_sahf_1"
973   [(set (reg:CC FLAGS_REG)
974         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
975   "!TARGET_64BIT"
976   "sahf"
977   [(set_attr "length" "1")
978    (set_attr "athlon_decode" "vector")
979    (set_attr "mode" "SI")])
981 ;; Pentium Pro can do steps 1 through 3 in one go.
983 (define_insn "*cmpfp_i_mixed"
984   [(set (reg:CCFP FLAGS_REG)
985         (compare:CCFP (match_operand 0 "register_operand" "f,x")
986                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
987   "TARGET_MIX_SSE_I387
988    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990   "* return output_fp_compare (insn, operands, 1, 0);"
991   [(set_attr "type" "fcmp,ssecomi")
992    (set (attr "mode")
993      (if_then_else (match_operand:SF 1 "" "")
994         (const_string "SF")
995         (const_string "DF")))
996    (set_attr "athlon_decode" "vector")])
998 (define_insn "*cmpfp_i_sse"
999   [(set (reg:CCFP FLAGS_REG)
1000         (compare:CCFP (match_operand 0 "register_operand" "x")
1001                       (match_operand 1 "nonimmediate_operand" "xm")))]
1002   "TARGET_SSE_MATH
1003    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1004    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1005   "* return output_fp_compare (insn, operands, 1, 0);"
1006   [(set_attr "type" "ssecomi")
1007    (set (attr "mode")
1008      (if_then_else (match_operand:SF 1 "" "")
1009         (const_string "SF")
1010         (const_string "DF")))
1011    (set_attr "athlon_decode" "vector")])
1013 (define_insn "*cmpfp_i_i387"
1014   [(set (reg:CCFP FLAGS_REG)
1015         (compare:CCFP (match_operand 0 "register_operand" "f")
1016                       (match_operand 1 "register_operand" "f")))]
1017   "TARGET_80387 && TARGET_CMOVE
1018    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1019    && FLOAT_MODE_P (GET_MODE (operands[0]))
1020    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1021   "* return output_fp_compare (insn, operands, 1, 0);"
1022   [(set_attr "type" "fcmp")
1023    (set (attr "mode")
1024      (cond [(match_operand:SF 1 "" "")
1025               (const_string "SF")
1026             (match_operand:DF 1 "" "")
1027               (const_string "DF")
1028            ]
1029            (const_string "XF")))
1030    (set_attr "athlon_decode" "vector")])
1032 (define_insn "*cmpfp_iu_mixed"
1033   [(set (reg:CCFPU FLAGS_REG)
1034         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1035                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1036   "TARGET_MIX_SSE_I387
1037    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039   "* return output_fp_compare (insn, operands, 1, 1);"
1040   [(set_attr "type" "fcmp,ssecomi")
1041    (set (attr "mode")
1042      (if_then_else (match_operand:SF 1 "" "")
1043         (const_string "SF")
1044         (const_string "DF")))
1045    (set_attr "athlon_decode" "vector")])
1047 (define_insn "*cmpfp_iu_sse"
1048   [(set (reg:CCFPU FLAGS_REG)
1049         (compare:CCFPU (match_operand 0 "register_operand" "x")
1050                        (match_operand 1 "nonimmediate_operand" "xm")))]
1051   "TARGET_SSE_MATH
1052    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1053    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1054   "* return output_fp_compare (insn, operands, 1, 1);"
1055   [(set_attr "type" "ssecomi")
1056    (set (attr "mode")
1057      (if_then_else (match_operand:SF 1 "" "")
1058         (const_string "SF")
1059         (const_string "DF")))
1060    (set_attr "athlon_decode" "vector")])
1062 (define_insn "*cmpfp_iu_387"
1063   [(set (reg:CCFPU FLAGS_REG)
1064         (compare:CCFPU (match_operand 0 "register_operand" "f")
1065                        (match_operand 1 "register_operand" "f")))]
1066   "TARGET_80387 && TARGET_CMOVE
1067    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1068    && FLOAT_MODE_P (GET_MODE (operands[0]))
1069    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1070   "* return output_fp_compare (insn, operands, 1, 1);"
1071   [(set_attr "type" "fcmp")
1072    (set (attr "mode")
1073      (cond [(match_operand:SF 1 "" "")
1074               (const_string "SF")
1075             (match_operand:DF 1 "" "")
1076               (const_string "DF")
1077            ]
1078            (const_string "XF")))
1079    (set_attr "athlon_decode" "vector")])
1081 ;; Move instructions.
1083 ;; General case of fullword move.
1085 (define_expand "movsi"
1086   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1087         (match_operand:SI 1 "general_operand" ""))]
1088   ""
1089   "ix86_expand_move (SImode, operands); DONE;")
1091 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1092 ;; general_operand.
1094 ;; %%% We don't use a post-inc memory reference because x86 is not a
1095 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1096 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1097 ;; targets without our curiosities, and it is just as easy to represent
1098 ;; this differently.
1100 (define_insn "*pushsi2"
1101   [(set (match_operand:SI 0 "push_operand" "=<")
1102         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1103   "!TARGET_64BIT"
1104   "push{l}\t%1"
1105   [(set_attr "type" "push")
1106    (set_attr "mode" "SI")])
1108 ;; For 64BIT abi we always round up to 8 bytes.
1109 (define_insn "*pushsi2_rex64"
1110   [(set (match_operand:SI 0 "push_operand" "=X")
1111         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1112   "TARGET_64BIT"
1113   "push{q}\t%q1"
1114   [(set_attr "type" "push")
1115    (set_attr "mode" "SI")])
1117 (define_insn "*pushsi2_prologue"
1118   [(set (match_operand:SI 0 "push_operand" "=<")
1119         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1120    (clobber (mem:BLK (scratch)))]
1121   "!TARGET_64BIT"
1122   "push{l}\t%1"
1123   [(set_attr "type" "push")
1124    (set_attr "mode" "SI")])
1126 (define_insn "*popsi1_epilogue"
1127   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1128         (mem:SI (reg:SI SP_REG)))
1129    (set (reg:SI SP_REG)
1130         (plus:SI (reg:SI SP_REG) (const_int 4)))
1131    (clobber (mem:BLK (scratch)))]
1132   "!TARGET_64BIT"
1133   "pop{l}\t%0"
1134   [(set_attr "type" "pop")
1135    (set_attr "mode" "SI")])
1137 (define_insn "popsi1"
1138   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1139         (mem:SI (reg:SI SP_REG)))
1140    (set (reg:SI SP_REG)
1141         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1142   "!TARGET_64BIT"
1143   "pop{l}\t%0"
1144   [(set_attr "type" "pop")
1145    (set_attr "mode" "SI")])
1147 (define_insn "*movsi_xor"
1148   [(set (match_operand:SI 0 "register_operand" "=r")
1149         (match_operand:SI 1 "const0_operand" "i"))
1150    (clobber (reg:CC FLAGS_REG))]
1151   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1152   "xor{l}\t{%0, %0|%0, %0}"
1153   [(set_attr "type" "alu1")
1154    (set_attr "mode" "SI")
1155    (set_attr "length_immediate" "0")])
1157 (define_insn "*movsi_or"
1158   [(set (match_operand:SI 0 "register_operand" "=r")
1159         (match_operand:SI 1 "immediate_operand" "i"))
1160    (clobber (reg:CC FLAGS_REG))]
1161   "reload_completed
1162    && operands[1] == constm1_rtx
1163    && (TARGET_PENTIUM || optimize_size)"
1165   operands[1] = constm1_rtx;
1166   return "or{l}\t{%1, %0|%0, %1}";
1168   [(set_attr "type" "alu1")
1169    (set_attr "mode" "SI")
1170    (set_attr "length_immediate" "1")])
1172 (define_insn "*movsi_1"
1173   [(set (match_operand:SI 0 "nonimmediate_operand"
1174                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1175         (match_operand:SI 1 "general_operand"
1176                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1177   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1179   switch (get_attr_type (insn))
1180     {
1181     case TYPE_SSELOG1:
1182       if (get_attr_mode (insn) == MODE_TI)
1183         return "pxor\t%0, %0";
1184       return "xorps\t%0, %0";
1186     case TYPE_SSEMOV:
1187       switch (get_attr_mode (insn))
1188         {
1189         case MODE_TI:
1190           return "movdqa\t{%1, %0|%0, %1}";
1191         case MODE_V4SF:
1192           return "movaps\t{%1, %0|%0, %1}";
1193         case MODE_SI:
1194           return "movd\t{%1, %0|%0, %1}";
1195         case MODE_SF:
1196           return "movss\t{%1, %0|%0, %1}";
1197         default:
1198           gcc_unreachable ();
1199         }
1201     case TYPE_MMXADD:
1202       return "pxor\t%0, %0";
1204     case TYPE_MMXMOV:
1205       if (get_attr_mode (insn) == MODE_DI)
1206         return "movq\t{%1, %0|%0, %1}";
1207       return "movd\t{%1, %0|%0, %1}";
1209     case TYPE_LEA:
1210       return "lea{l}\t{%1, %0|%0, %1}";
1212     default:
1213       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1214       return "mov{l}\t{%1, %0|%0, %1}";
1215     }
1217   [(set (attr "type")
1218      (cond [(eq_attr "alternative" "2")
1219               (const_string "mmxadd")
1220             (eq_attr "alternative" "3,4,5")
1221               (const_string "mmxmov")
1222             (eq_attr "alternative" "6")
1223               (const_string "sselog1")
1224             (eq_attr "alternative" "7,8,9,10,11")
1225               (const_string "ssemov")
1226             (match_operand:DI 1 "pic_32bit_operand" "")
1227               (const_string "lea")
1228            ]
1229            (const_string "imov")))
1230    (set (attr "mode")
1231      (cond [(eq_attr "alternative" "2,3")
1232               (const_string "DI")
1233             (eq_attr "alternative" "6,7")
1234               (if_then_else
1235                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1236                 (const_string "V4SF")
1237                 (const_string "TI"))
1238             (and (eq_attr "alternative" "8,9,10,11")
1239                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1240               (const_string "SF")
1241            ]
1242            (const_string "SI")))])
1244 ;; Stores and loads of ax to arbitrary constant address.
1245 ;; We fake an second form of instruction to force reload to load address
1246 ;; into register when rax is not available
1247 (define_insn "*movabssi_1_rex64"
1248   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1249         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1250   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1251   "@
1252    movabs{l}\t{%1, %P0|%P0, %1}
1253    mov{l}\t{%1, %a0|%a0, %1}"
1254   [(set_attr "type" "imov")
1255    (set_attr "modrm" "0,*")
1256    (set_attr "length_address" "8,0")
1257    (set_attr "length_immediate" "0,*")
1258    (set_attr "memory" "store")
1259    (set_attr "mode" "SI")])
1261 (define_insn "*movabssi_2_rex64"
1262   [(set (match_operand:SI 0 "register_operand" "=a,r")
1263         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1264   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1265   "@
1266    movabs{l}\t{%P1, %0|%0, %P1}
1267    mov{l}\t{%a1, %0|%0, %a1}"
1268   [(set_attr "type" "imov")
1269    (set_attr "modrm" "0,*")
1270    (set_attr "length_address" "8,0")
1271    (set_attr "length_immediate" "0")
1272    (set_attr "memory" "load")
1273    (set_attr "mode" "SI")])
1275 (define_insn "*swapsi"
1276   [(set (match_operand:SI 0 "register_operand" "+r")
1277         (match_operand:SI 1 "register_operand" "+r"))
1278    (set (match_dup 1)
1279         (match_dup 0))]
1280   ""
1281   "xchg{l}\t%1, %0"
1282   [(set_attr "type" "imov")
1283    (set_attr "mode" "SI")
1284    (set_attr "pent_pair" "np")
1285    (set_attr "athlon_decode" "vector")])
1287 (define_expand "movhi"
1288   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1289         (match_operand:HI 1 "general_operand" ""))]
1290   ""
1291   "ix86_expand_move (HImode, operands); DONE;")
1293 (define_insn "*pushhi2"
1294   [(set (match_operand:HI 0 "push_operand" "=X")
1295         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1296   "!TARGET_64BIT"
1297   "push{l}\t%k1"
1298   [(set_attr "type" "push")
1299    (set_attr "mode" "SI")])
1301 ;; For 64BIT abi we always round up to 8 bytes.
1302 (define_insn "*pushhi2_rex64"
1303   [(set (match_operand:HI 0 "push_operand" "=X")
1304         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1305   "TARGET_64BIT"
1306   "push{q}\t%q1"
1307   [(set_attr "type" "push")
1308    (set_attr "mode" "DI")])
1310 (define_insn "*movhi_1"
1311   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1312         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1313   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1315   switch (get_attr_type (insn))
1316     {
1317     case TYPE_IMOVX:
1318       /* movzwl is faster than movw on p2 due to partial word stalls,
1319          though not as fast as an aligned movl.  */
1320       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1321     default:
1322       if (get_attr_mode (insn) == MODE_SI)
1323         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1324       else
1325         return "mov{w}\t{%1, %0|%0, %1}";
1326     }
1328   [(set (attr "type")
1329      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1330               (const_string "imov")
1331             (and (eq_attr "alternative" "0")
1332                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1333                           (const_int 0))
1334                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1335                           (const_int 0))))
1336               (const_string "imov")
1337             (and (eq_attr "alternative" "1,2")
1338                  (match_operand:HI 1 "aligned_operand" ""))
1339               (const_string "imov")
1340             (and (ne (symbol_ref "TARGET_MOVX")
1341                      (const_int 0))
1342                  (eq_attr "alternative" "0,2"))
1343               (const_string "imovx")
1344            ]
1345            (const_string "imov")))
1346     (set (attr "mode")
1347       (cond [(eq_attr "type" "imovx")
1348                (const_string "SI")
1349              (and (eq_attr "alternative" "1,2")
1350                   (match_operand:HI 1 "aligned_operand" ""))
1351                (const_string "SI")
1352              (and (eq_attr "alternative" "0")
1353                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1354                            (const_int 0))
1355                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1356                            (const_int 0))))
1357                (const_string "SI")
1358             ]
1359             (const_string "HI")))])
1361 ;; Stores and loads of ax to arbitrary constant address.
1362 ;; We fake an second form of instruction to force reload to load address
1363 ;; into register when rax is not available
1364 (define_insn "*movabshi_1_rex64"
1365   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1366         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1367   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1368   "@
1369    movabs{w}\t{%1, %P0|%P0, %1}
1370    mov{w}\t{%1, %a0|%a0, %1}"
1371   [(set_attr "type" "imov")
1372    (set_attr "modrm" "0,*")
1373    (set_attr "length_address" "8,0")
1374    (set_attr "length_immediate" "0,*")
1375    (set_attr "memory" "store")
1376    (set_attr "mode" "HI")])
1378 (define_insn "*movabshi_2_rex64"
1379   [(set (match_operand:HI 0 "register_operand" "=a,r")
1380         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1381   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1382   "@
1383    movabs{w}\t{%P1, %0|%0, %P1}
1384    mov{w}\t{%a1, %0|%0, %a1}"
1385   [(set_attr "type" "imov")
1386    (set_attr "modrm" "0,*")
1387    (set_attr "length_address" "8,0")
1388    (set_attr "length_immediate" "0")
1389    (set_attr "memory" "load")
1390    (set_attr "mode" "HI")])
1392 (define_insn "*swaphi_1"
1393   [(set (match_operand:HI 0 "register_operand" "+r")
1394         (match_operand:HI 1 "register_operand" "+r"))
1395    (set (match_dup 1)
1396         (match_dup 0))]
1397   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1398   "xchg{l}\t%k1, %k0"
1399   [(set_attr "type" "imov")
1400    (set_attr "mode" "SI")
1401    (set_attr "pent_pair" "np")
1402    (set_attr "athlon_decode" "vector")])
1404 (define_insn "*swaphi_2"
1405   [(set (match_operand:HI 0 "register_operand" "+r")
1406         (match_operand:HI 1 "register_operand" "+r"))
1407    (set (match_dup 1)
1408         (match_dup 0))]
1409   "TARGET_PARTIAL_REG_STALL"
1410   "xchg{w}\t%1, %0"
1411   [(set_attr "type" "imov")
1412    (set_attr "mode" "HI")
1413    (set_attr "pent_pair" "np")
1414    (set_attr "athlon_decode" "vector")])
1416 (define_expand "movstricthi"
1417   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1418         (match_operand:HI 1 "general_operand" ""))]
1419   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1421   /* Don't generate memory->memory moves, go through a register */
1422   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1423     operands[1] = force_reg (HImode, operands[1]);
1426 (define_insn "*movstricthi_1"
1427   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1428         (match_operand:HI 1 "general_operand" "rn,m"))]
1429   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1430    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1431   "mov{w}\t{%1, %0|%0, %1}"
1432   [(set_attr "type" "imov")
1433    (set_attr "mode" "HI")])
1435 (define_insn "*movstricthi_xor"
1436   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1437         (match_operand:HI 1 "const0_operand" "i"))
1438    (clobber (reg:CC FLAGS_REG))]
1439   "reload_completed
1440    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1441   "xor{w}\t{%0, %0|%0, %0}"
1442   [(set_attr "type" "alu1")
1443    (set_attr "mode" "HI")
1444    (set_attr "length_immediate" "0")])
1446 (define_expand "movqi"
1447   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1448         (match_operand:QI 1 "general_operand" ""))]
1449   ""
1450   "ix86_expand_move (QImode, operands); DONE;")
1452 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1453 ;; "push a byte".  But actually we use pushl, which has the effect
1454 ;; of rounding the amount pushed up to a word.
1456 (define_insn "*pushqi2"
1457   [(set (match_operand:QI 0 "push_operand" "=X")
1458         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1459   "!TARGET_64BIT"
1460   "push{l}\t%k1"
1461   [(set_attr "type" "push")
1462    (set_attr "mode" "SI")])
1464 ;; For 64BIT abi we always round up to 8 bytes.
1465 (define_insn "*pushqi2_rex64"
1466   [(set (match_operand:QI 0 "push_operand" "=X")
1467         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1468   "TARGET_64BIT"
1469   "push{q}\t%q1"
1470   [(set_attr "type" "push")
1471    (set_attr "mode" "DI")])
1473 ;; Situation is quite tricky about when to choose full sized (SImode) move
1474 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1475 ;; partial register dependency machines (such as AMD Athlon), where QImode
1476 ;; moves issue extra dependency and for partial register stalls machines
1477 ;; that don't use QImode patterns (and QImode move cause stall on the next
1478 ;; instruction).
1480 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1481 ;; register stall machines with, where we use QImode instructions, since
1482 ;; partial register stall can be caused there.  Then we use movzx.
1483 (define_insn "*movqi_1"
1484   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1485         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1486   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1488   switch (get_attr_type (insn))
1489     {
1490     case TYPE_IMOVX:
1491       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1492       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1493     default:
1494       if (get_attr_mode (insn) == MODE_SI)
1495         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1496       else
1497         return "mov{b}\t{%1, %0|%0, %1}";
1498     }
1500   [(set (attr "type")
1501      (cond [(and (eq_attr "alternative" "5")
1502                  (not (match_operand:QI 1 "aligned_operand" "")))
1503               (const_string "imovx")
1504             (ne (symbol_ref "optimize_size") (const_int 0))
1505               (const_string "imov")
1506             (and (eq_attr "alternative" "3")
1507                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1508                           (const_int 0))
1509                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1510                           (const_int 0))))
1511               (const_string "imov")
1512             (eq_attr "alternative" "3,5")
1513               (const_string "imovx")
1514             (and (ne (symbol_ref "TARGET_MOVX")
1515                      (const_int 0))
1516                  (eq_attr "alternative" "2"))
1517               (const_string "imovx")
1518            ]
1519            (const_string "imov")))
1520    (set (attr "mode")
1521       (cond [(eq_attr "alternative" "3,4,5")
1522                (const_string "SI")
1523              (eq_attr "alternative" "6")
1524                (const_string "QI")
1525              (eq_attr "type" "imovx")
1526                (const_string "SI")
1527              (and (eq_attr "type" "imov")
1528                   (and (eq_attr "alternative" "0,1")
1529                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1530                                 (const_int 0))
1531                             (and (eq (symbol_ref "optimize_size")
1532                                      (const_int 0))
1533                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1534                                      (const_int 0))))))
1535                (const_string "SI")
1536              ;; Avoid partial register stalls when not using QImode arithmetic
1537              (and (eq_attr "type" "imov")
1538                   (and (eq_attr "alternative" "0,1")
1539                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1540                                 (const_int 0))
1541                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1542                                 (const_int 0)))))
1543                (const_string "SI")
1544            ]
1545            (const_string "QI")))])
1547 (define_expand "reload_outqi"
1548   [(parallel [(match_operand:QI 0 "" "=m")
1549               (match_operand:QI 1 "register_operand" "r")
1550               (match_operand:QI 2 "register_operand" "=&q")])]
1551   ""
1553   rtx op0, op1, op2;
1554   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1556   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1557   if (! q_regs_operand (op1, QImode))
1558     {
1559       emit_insn (gen_movqi (op2, op1));
1560       op1 = op2;
1561     }
1562   emit_insn (gen_movqi (op0, op1));
1563   DONE;
1566 (define_insn "*swapqi_1"
1567   [(set (match_operand:QI 0 "register_operand" "+r")
1568         (match_operand:QI 1 "register_operand" "+r"))
1569    (set (match_dup 1)
1570         (match_dup 0))]
1571   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1572   "xchg{l}\t%k1, %k0"
1573   [(set_attr "type" "imov")
1574    (set_attr "mode" "SI")
1575    (set_attr "pent_pair" "np")
1576    (set_attr "athlon_decode" "vector")])
1578 (define_insn "*swapqi_2"
1579   [(set (match_operand:QI 0 "register_operand" "+q")
1580         (match_operand:QI 1 "register_operand" "+q"))
1581    (set (match_dup 1)
1582         (match_dup 0))]
1583   "TARGET_PARTIAL_REG_STALL"
1584   "xchg{b}\t%1, %0"
1585   [(set_attr "type" "imov")
1586    (set_attr "mode" "QI")
1587    (set_attr "pent_pair" "np")
1588    (set_attr "athlon_decode" "vector")])
1590 (define_expand "movstrictqi"
1591   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1592         (match_operand:QI 1 "general_operand" ""))]
1593   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1595   /* Don't generate memory->memory moves, go through a register.  */
1596   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1597     operands[1] = force_reg (QImode, operands[1]);
1600 (define_insn "*movstrictqi_1"
1601   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1602         (match_operand:QI 1 "general_operand" "*qn,m"))]
1603   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1604    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1605   "mov{b}\t{%1, %0|%0, %1}"
1606   [(set_attr "type" "imov")
1607    (set_attr "mode" "QI")])
1609 (define_insn "*movstrictqi_xor"
1610   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1611         (match_operand:QI 1 "const0_operand" "i"))
1612    (clobber (reg:CC FLAGS_REG))]
1613   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1614   "xor{b}\t{%0, %0|%0, %0}"
1615   [(set_attr "type" "alu1")
1616    (set_attr "mode" "QI")
1617    (set_attr "length_immediate" "0")])
1619 (define_insn "*movsi_extv_1"
1620   [(set (match_operand:SI 0 "register_operand" "=R")
1621         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1622                          (const_int 8)
1623                          (const_int 8)))]
1624   ""
1625   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1626   [(set_attr "type" "imovx")
1627    (set_attr "mode" "SI")])
1629 (define_insn "*movhi_extv_1"
1630   [(set (match_operand:HI 0 "register_operand" "=R")
1631         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1632                          (const_int 8)
1633                          (const_int 8)))]
1634   ""
1635   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1636   [(set_attr "type" "imovx")
1637    (set_attr "mode" "SI")])
1639 (define_insn "*movqi_extv_1"
1640   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1641         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1642                          (const_int 8)
1643                          (const_int 8)))]
1644   "!TARGET_64BIT"
1646   switch (get_attr_type (insn))
1647     {
1648     case TYPE_IMOVX:
1649       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1650     default:
1651       return "mov{b}\t{%h1, %0|%0, %h1}";
1652     }
1654   [(set (attr "type")
1655      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1656                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1657                              (ne (symbol_ref "TARGET_MOVX")
1658                                  (const_int 0))))
1659         (const_string "imovx")
1660         (const_string "imov")))
1661    (set (attr "mode")
1662      (if_then_else (eq_attr "type" "imovx")
1663         (const_string "SI")
1664         (const_string "QI")))])
1666 (define_insn "*movqi_extv_1_rex64"
1667   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1668         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1669                          (const_int 8)
1670                          (const_int 8)))]
1671   "TARGET_64BIT"
1673   switch (get_attr_type (insn))
1674     {
1675     case TYPE_IMOVX:
1676       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1677     default:
1678       return "mov{b}\t{%h1, %0|%0, %h1}";
1679     }
1681   [(set (attr "type")
1682      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1683                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1684                              (ne (symbol_ref "TARGET_MOVX")
1685                                  (const_int 0))))
1686         (const_string "imovx")
1687         (const_string "imov")))
1688    (set (attr "mode")
1689      (if_then_else (eq_attr "type" "imovx")
1690         (const_string "SI")
1691         (const_string "QI")))])
1693 ;; Stores and loads of ax to arbitrary constant address.
1694 ;; We fake an second form of instruction to force reload to load address
1695 ;; into register when rax is not available
1696 (define_insn "*movabsqi_1_rex64"
1697   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1698         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1699   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1700   "@
1701    movabs{b}\t{%1, %P0|%P0, %1}
1702    mov{b}\t{%1, %a0|%a0, %1}"
1703   [(set_attr "type" "imov")
1704    (set_attr "modrm" "0,*")
1705    (set_attr "length_address" "8,0")
1706    (set_attr "length_immediate" "0,*")
1707    (set_attr "memory" "store")
1708    (set_attr "mode" "QI")])
1710 (define_insn "*movabsqi_2_rex64"
1711   [(set (match_operand:QI 0 "register_operand" "=a,r")
1712         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1713   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1714   "@
1715    movabs{b}\t{%P1, %0|%0, %P1}
1716    mov{b}\t{%a1, %0|%0, %a1}"
1717   [(set_attr "type" "imov")
1718    (set_attr "modrm" "0,*")
1719    (set_attr "length_address" "8,0")
1720    (set_attr "length_immediate" "0")
1721    (set_attr "memory" "load")
1722    (set_attr "mode" "QI")])
1724 (define_insn "*movdi_extzv_1"
1725   [(set (match_operand:DI 0 "register_operand" "=R")
1726         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1727                          (const_int 8)
1728                          (const_int 8)))]
1729   "TARGET_64BIT"
1730   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1731   [(set_attr "type" "imovx")
1732    (set_attr "mode" "DI")])
1734 (define_insn "*movsi_extzv_1"
1735   [(set (match_operand:SI 0 "register_operand" "=R")
1736         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1737                          (const_int 8)
1738                          (const_int 8)))]
1739   ""
1740   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1741   [(set_attr "type" "imovx")
1742    (set_attr "mode" "SI")])
1744 (define_insn "*movqi_extzv_2"
1745   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1746         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1747                                     (const_int 8)
1748                                     (const_int 8)) 0))]
1749   "!TARGET_64BIT"
1751   switch (get_attr_type (insn))
1752     {
1753     case TYPE_IMOVX:
1754       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1755     default:
1756       return "mov{b}\t{%h1, %0|%0, %h1}";
1757     }
1759   [(set (attr "type")
1760      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1761                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1762                              (ne (symbol_ref "TARGET_MOVX")
1763                                  (const_int 0))))
1764         (const_string "imovx")
1765         (const_string "imov")))
1766    (set (attr "mode")
1767      (if_then_else (eq_attr "type" "imovx")
1768         (const_string "SI")
1769         (const_string "QI")))])
1771 (define_insn "*movqi_extzv_2_rex64"
1772   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1773         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1774                                     (const_int 8)
1775                                     (const_int 8)) 0))]
1776   "TARGET_64BIT"
1778   switch (get_attr_type (insn))
1779     {
1780     case TYPE_IMOVX:
1781       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1782     default:
1783       return "mov{b}\t{%h1, %0|%0, %h1}";
1784     }
1786   [(set (attr "type")
1787      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1788                         (ne (symbol_ref "TARGET_MOVX")
1789                             (const_int 0)))
1790         (const_string "imovx")
1791         (const_string "imov")))
1792    (set (attr "mode")
1793      (if_then_else (eq_attr "type" "imovx")
1794         (const_string "SI")
1795         (const_string "QI")))])
1797 (define_insn "movsi_insv_1"
1798   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1799                          (const_int 8)
1800                          (const_int 8))
1801         (match_operand:SI 1 "general_operand" "Qmn"))]
1802   "!TARGET_64BIT"
1803   "mov{b}\t{%b1, %h0|%h0, %b1}"
1804   [(set_attr "type" "imov")
1805    (set_attr "mode" "QI")])
1807 (define_insn "*movsi_insv_1_rex64"
1808   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1809                          (const_int 8)
1810                          (const_int 8))
1811         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1812   "TARGET_64BIT"
1813   "mov{b}\t{%b1, %h0|%h0, %b1}"
1814   [(set_attr "type" "imov")
1815    (set_attr "mode" "QI")])
1817 (define_insn "movdi_insv_1_rex64"
1818   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1819                          (const_int 8)
1820                          (const_int 8))
1821         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1822   "TARGET_64BIT"
1823   "mov{b}\t{%b1, %h0|%h0, %b1}"
1824   [(set_attr "type" "imov")
1825    (set_attr "mode" "QI")])
1827 (define_insn "*movqi_insv_2"
1828   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1829                          (const_int 8)
1830                          (const_int 8))
1831         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1832                      (const_int 8)))]
1833   ""
1834   "mov{b}\t{%h1, %h0|%h0, %h1}"
1835   [(set_attr "type" "imov")
1836    (set_attr "mode" "QI")])
1838 (define_expand "movdi"
1839   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1840         (match_operand:DI 1 "general_operand" ""))]
1841   ""
1842   "ix86_expand_move (DImode, operands); DONE;")
1844 (define_insn "*pushdi"
1845   [(set (match_operand:DI 0 "push_operand" "=<")
1846         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1847   "!TARGET_64BIT"
1848   "#")
1850 (define_insn "*pushdi2_rex64"
1851   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1852         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1853   "TARGET_64BIT"
1854   "@
1855    push{q}\t%1
1856    #"
1857   [(set_attr "type" "push,multi")
1858    (set_attr "mode" "DI")])
1860 ;; Convert impossible pushes of immediate to existing instructions.
1861 ;; First try to get scratch register and go through it.  In case this
1862 ;; fails, push sign extended lower part first and then overwrite
1863 ;; upper part by 32bit move.
1864 (define_peephole2
1865   [(match_scratch:DI 2 "r")
1866    (set (match_operand:DI 0 "push_operand" "")
1867         (match_operand:DI 1 "immediate_operand" ""))]
1868   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1869    && !x86_64_immediate_operand (operands[1], DImode)"
1870   [(set (match_dup 2) (match_dup 1))
1871    (set (match_dup 0) (match_dup 2))]
1872   "")
1874 ;; We need to define this as both peepholer and splitter for case
1875 ;; peephole2 pass is not run.
1876 ;; "&& 1" is needed to keep it from matching the previous pattern.
1877 (define_peephole2
1878   [(set (match_operand:DI 0 "push_operand" "")
1879         (match_operand:DI 1 "immediate_operand" ""))]
1880   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1881    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1882   [(set (match_dup 0) (match_dup 1))
1883    (set (match_dup 2) (match_dup 3))]
1884   "split_di (operands + 1, 1, operands + 2, operands + 3);
1885    operands[1] = gen_lowpart (DImode, operands[2]);
1886    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1887                                                     GEN_INT (4)));
1888   ")
1890 (define_split
1891   [(set (match_operand:DI 0 "push_operand" "")
1892         (match_operand:DI 1 "immediate_operand" ""))]
1893   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1894                     ? flow2_completed : reload_completed)
1895    && !symbolic_operand (operands[1], DImode)
1896    && !x86_64_immediate_operand (operands[1], DImode)"
1897   [(set (match_dup 0) (match_dup 1))
1898    (set (match_dup 2) (match_dup 3))]
1899   "split_di (operands + 1, 1, operands + 2, operands + 3);
1900    operands[1] = gen_lowpart (DImode, operands[2]);
1901    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1902                                                     GEN_INT (4)));
1903   ")
1905 (define_insn "*pushdi2_prologue_rex64"
1906   [(set (match_operand:DI 0 "push_operand" "=<")
1907         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1908    (clobber (mem:BLK (scratch)))]
1909   "TARGET_64BIT"
1910   "push{q}\t%1"
1911   [(set_attr "type" "push")
1912    (set_attr "mode" "DI")])
1914 (define_insn "*popdi1_epilogue_rex64"
1915   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1916         (mem:DI (reg:DI SP_REG)))
1917    (set (reg:DI SP_REG)
1918         (plus:DI (reg:DI SP_REG) (const_int 8)))
1919    (clobber (mem:BLK (scratch)))]
1920   "TARGET_64BIT"
1921   "pop{q}\t%0"
1922   [(set_attr "type" "pop")
1923    (set_attr "mode" "DI")])
1925 (define_insn "popdi1"
1926   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1927         (mem:DI (reg:DI SP_REG)))
1928    (set (reg:DI SP_REG)
1929         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1930   "TARGET_64BIT"
1931   "pop{q}\t%0"
1932   [(set_attr "type" "pop")
1933    (set_attr "mode" "DI")])
1935 (define_insn "*movdi_xor_rex64"
1936   [(set (match_operand:DI 0 "register_operand" "=r")
1937         (match_operand:DI 1 "const0_operand" "i"))
1938    (clobber (reg:CC FLAGS_REG))]
1939   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1940    && reload_completed"
1941   "xor{l}\t{%k0, %k0|%k0, %k0}"
1942   [(set_attr "type" "alu1")
1943    (set_attr "mode" "SI")
1944    (set_attr "length_immediate" "0")])
1946 (define_insn "*movdi_or_rex64"
1947   [(set (match_operand:DI 0 "register_operand" "=r")
1948         (match_operand:DI 1 "const_int_operand" "i"))
1949    (clobber (reg:CC FLAGS_REG))]
1950   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1951    && reload_completed
1952    && operands[1] == constm1_rtx"
1954   operands[1] = constm1_rtx;
1955   return "or{q}\t{%1, %0|%0, %1}";
1957   [(set_attr "type" "alu1")
1958    (set_attr "mode" "DI")
1959    (set_attr "length_immediate" "1")])
1961 (define_insn "*movdi_2"
1962   [(set (match_operand:DI 0 "nonimmediate_operand"
1963                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1964         (match_operand:DI 1 "general_operand"
1965                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1966   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1967   "@
1968    #
1969    #
1970    pxor\t%0, %0
1971    movq\t{%1, %0|%0, %1}
1972    movq\t{%1, %0|%0, %1}
1973    pxor\t%0, %0
1974    movq\t{%1, %0|%0, %1}
1975    movdqa\t{%1, %0|%0, %1}
1976    movq\t{%1, %0|%0, %1}
1977    xorps\t%0, %0
1978    movlps\t{%1, %0|%0, %1}
1979    movaps\t{%1, %0|%0, %1}
1980    movlps\t{%1, %0|%0, %1}"
1981   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1982    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1984 (define_split
1985   [(set (match_operand:DI 0 "push_operand" "")
1986         (match_operand:DI 1 "general_operand" ""))]
1987   "!TARGET_64BIT && reload_completed
1988    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1989   [(const_int 0)]
1990   "ix86_split_long_move (operands); DONE;")
1992 ;; %%% This multiword shite has got to go.
1993 (define_split
1994   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1995         (match_operand:DI 1 "general_operand" ""))]
1996   "!TARGET_64BIT && reload_completed
1997    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1998    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1999   [(const_int 0)]
2000   "ix86_split_long_move (operands); DONE;")
2002 (define_insn "*movdi_1_rex64"
2003   [(set (match_operand:DI 0 "nonimmediate_operand"
2004                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2005         (match_operand:DI 1 "general_operand"
2006                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2007   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2009   switch (get_attr_type (insn))
2010     {
2011     case TYPE_SSECVT:
2012       if (which_alternative == 13)
2013         return "movq2dq\t{%1, %0|%0, %1}";
2014       else
2015         return "movdq2q\t{%1, %0|%0, %1}";
2016     case TYPE_SSEMOV:
2017       if (get_attr_mode (insn) == MODE_TI)
2018           return "movdqa\t{%1, %0|%0, %1}";
2019       /* FALLTHRU */
2020     case TYPE_MMXMOV:
2021       /* Moves from and into integer register is done using movd opcode with
2022          REX prefix.  */
2023       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2024           return "movd\t{%1, %0|%0, %1}";
2025       return "movq\t{%1, %0|%0, %1}";
2026     case TYPE_SSELOG1:
2027     case TYPE_MMXADD:
2028       return "pxor\t%0, %0";
2029     case TYPE_MULTI:
2030       return "#";
2031     case TYPE_LEA:
2032       return "lea{q}\t{%a1, %0|%0, %a1}";
2033     default:
2034       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2035       if (get_attr_mode (insn) == MODE_SI)
2036         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2037       else if (which_alternative == 2)
2038         return "movabs{q}\t{%1, %0|%0, %1}";
2039       else
2040         return "mov{q}\t{%1, %0|%0, %1}";
2041     }
2043   [(set (attr "type")
2044      (cond [(eq_attr "alternative" "5")
2045               (const_string "mmxadd")
2046             (eq_attr "alternative" "6,7,8")
2047               (const_string "mmxmov")
2048             (eq_attr "alternative" "9")
2049               (const_string "sselog1")
2050             (eq_attr "alternative" "10,11,12")
2051               (const_string "ssemov")
2052             (eq_attr "alternative" "13,14")
2053               (const_string "ssecvt")
2054             (eq_attr "alternative" "4")
2055               (const_string "multi")
2056             (match_operand:DI 1 "pic_32bit_operand" "")
2057               (const_string "lea")
2058            ]
2059            (const_string "imov")))
2060    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2061    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2062    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2064 ;; Stores and loads of ax to arbitrary constant address.
2065 ;; We fake an second form of instruction to force reload to load address
2066 ;; into register when rax is not available
2067 (define_insn "*movabsdi_1_rex64"
2068   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2069         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2070   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2071   "@
2072    movabs{q}\t{%1, %P0|%P0, %1}
2073    mov{q}\t{%1, %a0|%a0, %1}"
2074   [(set_attr "type" "imov")
2075    (set_attr "modrm" "0,*")
2076    (set_attr "length_address" "8,0")
2077    (set_attr "length_immediate" "0,*")
2078    (set_attr "memory" "store")
2079    (set_attr "mode" "DI")])
2081 (define_insn "*movabsdi_2_rex64"
2082   [(set (match_operand:DI 0 "register_operand" "=a,r")
2083         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2084   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2085   "@
2086    movabs{q}\t{%P1, %0|%0, %P1}
2087    mov{q}\t{%a1, %0|%0, %a1}"
2088   [(set_attr "type" "imov")
2089    (set_attr "modrm" "0,*")
2090    (set_attr "length_address" "8,0")
2091    (set_attr "length_immediate" "0")
2092    (set_attr "memory" "load")
2093    (set_attr "mode" "DI")])
2095 ;; Convert impossible stores of immediate to existing instructions.
2096 ;; First try to get scratch register and go through it.  In case this
2097 ;; fails, move by 32bit parts.
2098 (define_peephole2
2099   [(match_scratch:DI 2 "r")
2100    (set (match_operand:DI 0 "memory_operand" "")
2101         (match_operand:DI 1 "immediate_operand" ""))]
2102   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2103    && !x86_64_immediate_operand (operands[1], DImode)"
2104   [(set (match_dup 2) (match_dup 1))
2105    (set (match_dup 0) (match_dup 2))]
2106   "")
2108 ;; We need to define this as both peepholer and splitter for case
2109 ;; peephole2 pass is not run.
2110 ;; "&& 1" is needed to keep it from matching the previous pattern.
2111 (define_peephole2
2112   [(set (match_operand:DI 0 "memory_operand" "")
2113         (match_operand:DI 1 "immediate_operand" ""))]
2114   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2115    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2116   [(set (match_dup 2) (match_dup 3))
2117    (set (match_dup 4) (match_dup 5))]
2118   "split_di (operands, 2, operands + 2, operands + 4);")
2120 (define_split
2121   [(set (match_operand:DI 0 "memory_operand" "")
2122         (match_operand:DI 1 "immediate_operand" ""))]
2123   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2124                     ? flow2_completed : reload_completed)
2125    && !symbolic_operand (operands[1], DImode)
2126    && !x86_64_immediate_operand (operands[1], DImode)"
2127   [(set (match_dup 2) (match_dup 3))
2128    (set (match_dup 4) (match_dup 5))]
2129   "split_di (operands, 2, operands + 2, operands + 4);")
2131 (define_insn "*swapdi_rex64"
2132   [(set (match_operand:DI 0 "register_operand" "+r")
2133         (match_operand:DI 1 "register_operand" "+r"))
2134    (set (match_dup 1)
2135         (match_dup 0))]
2136   "TARGET_64BIT"
2137   "xchg{q}\t%1, %0"
2138   [(set_attr "type" "imov")
2139    (set_attr "mode" "DI")
2140    (set_attr "pent_pair" "np")
2141    (set_attr "athlon_decode" "vector")])
2143 (define_expand "movti"
2144   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2145         (match_operand:TI 1 "nonimmediate_operand" ""))]
2146   "TARGET_SSE || TARGET_64BIT"
2148   if (TARGET_64BIT)
2149     ix86_expand_move (TImode, operands);
2150   else
2151     ix86_expand_vector_move (TImode, operands);
2152   DONE;
2155 (define_insn "*movti_internal"
2156   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2157         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2158   "TARGET_SSE && !TARGET_64BIT
2159    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2161   switch (which_alternative)
2162     {
2163     case 0:
2164       if (get_attr_mode (insn) == MODE_V4SF)
2165         return "xorps\t%0, %0";
2166       else
2167         return "pxor\t%0, %0";
2168     case 1:
2169     case 2:
2170       if (get_attr_mode (insn) == MODE_V4SF)
2171         return "movaps\t{%1, %0|%0, %1}";
2172       else
2173         return "movdqa\t{%1, %0|%0, %1}";
2174     default:
2175       gcc_unreachable ();
2176     }
2178   [(set_attr "type" "sselog1,ssemov,ssemov")
2179    (set (attr "mode")
2180         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2181                     (ne (symbol_ref "optimize_size") (const_int 0)))
2182                  (const_string "V4SF")
2183                (and (eq_attr "alternative" "2")
2184                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2185                         (const_int 0)))
2186                  (const_string "V4SF")]
2187               (const_string "TI")))])
2189 (define_insn "*movti_rex64"
2190   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2191         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2192   "TARGET_64BIT
2193    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2195   switch (which_alternative)
2196     {
2197     case 0:
2198     case 1:
2199       return "#";
2200     case 2:
2201       if (get_attr_mode (insn) == MODE_V4SF)
2202         return "xorps\t%0, %0";
2203       else
2204         return "pxor\t%0, %0";
2205     case 3:
2206     case 4:
2207       if (get_attr_mode (insn) == MODE_V4SF)
2208         return "movaps\t{%1, %0|%0, %1}";
2209       else
2210         return "movdqa\t{%1, %0|%0, %1}";
2211     default:
2212       gcc_unreachable ();
2213     }
2215   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2216    (set (attr "mode")
2217         (cond [(eq_attr "alternative" "2,3")
2218                  (if_then_else
2219                    (ne (symbol_ref "optimize_size")
2220                        (const_int 0))
2221                    (const_string "V4SF")
2222                    (const_string "TI"))
2223                (eq_attr "alternative" "4")
2224                  (if_then_else
2225                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2226                             (const_int 0))
2227                         (ne (symbol_ref "optimize_size")
2228                             (const_int 0)))
2229                    (const_string "V4SF")
2230                    (const_string "TI"))]
2231                (const_string "DI")))])
2233 (define_split
2234   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2235         (match_operand:TI 1 "general_operand" ""))]
2236   "reload_completed && !SSE_REG_P (operands[0])
2237    && !SSE_REG_P (operands[1])"
2238   [(const_int 0)]
2239   "ix86_split_long_move (operands); DONE;")
2241 (define_expand "movsf"
2242   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2243         (match_operand:SF 1 "general_operand" ""))]
2244   ""
2245   "ix86_expand_move (SFmode, operands); DONE;")
2247 (define_insn "*pushsf"
2248   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2249         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2250   "!TARGET_64BIT"
2252   /* Anything else should be already split before reg-stack.  */
2253   gcc_assert (which_alternative == 1);
2254   return "push{l}\t%1";
2256   [(set_attr "type" "multi,push,multi")
2257    (set_attr "unit" "i387,*,*")
2258    (set_attr "mode" "SF,SI,SF")])
2260 (define_insn "*pushsf_rex64"
2261   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2262         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2263   "TARGET_64BIT"
2265   /* Anything else should be already split before reg-stack.  */
2266   gcc_assert (which_alternative == 1);
2267   return "push{q}\t%q1";
2269   [(set_attr "type" "multi,push,multi")
2270    (set_attr "unit" "i387,*,*")
2271    (set_attr "mode" "SF,DI,SF")])
2273 (define_split
2274   [(set (match_operand:SF 0 "push_operand" "")
2275         (match_operand:SF 1 "memory_operand" ""))]
2276   "reload_completed
2277    && MEM_P (operands[1])
2278    && constant_pool_reference_p (operands[1])"
2279   [(set (match_dup 0)
2280         (match_dup 1))]
2281   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2284 ;; %%% Kill this when call knows how to work this out.
2285 (define_split
2286   [(set (match_operand:SF 0 "push_operand" "")
2287         (match_operand:SF 1 "any_fp_register_operand" ""))]
2288   "!TARGET_64BIT"
2289   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2290    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2292 (define_split
2293   [(set (match_operand:SF 0 "push_operand" "")
2294         (match_operand:SF 1 "any_fp_register_operand" ""))]
2295   "TARGET_64BIT"
2296   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2297    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2299 (define_insn "*movsf_1"
2300   [(set (match_operand:SF 0 "nonimmediate_operand"
2301           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2302         (match_operand:SF 1 "general_operand"
2303           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2304   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2305    && (reload_in_progress || reload_completed
2306        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2307        || (!TARGET_SSE_MATH && optimize_size
2308            && standard_80387_constant_p (operands[1]))
2309        || GET_CODE (operands[1]) != CONST_DOUBLE
2310        || memory_operand (operands[0], SFmode))"
2312   switch (which_alternative)
2313     {
2314     case 0:
2315       return output_387_reg_move (insn, operands);
2317     case 1:
2318       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2319         return "fstp%z0\t%y0";
2320       else
2321         return "fst%z0\t%y0";
2323     case 2:
2324       return standard_80387_constant_opcode (operands[1]);
2326     case 3:
2327     case 4:
2328       return "mov{l}\t{%1, %0|%0, %1}";
2329     case 5:
2330       if (get_attr_mode (insn) == MODE_TI)
2331         return "pxor\t%0, %0";
2332       else
2333         return "xorps\t%0, %0";
2334     case 6:
2335       if (get_attr_mode (insn) == MODE_V4SF)
2336         return "movaps\t{%1, %0|%0, %1}";
2337       else
2338         return "movss\t{%1, %0|%0, %1}";
2339     case 7:
2340     case 8:
2341       return "movss\t{%1, %0|%0, %1}";
2343     case 9:
2344     case 10:
2345       return "movd\t{%1, %0|%0, %1}";
2347     case 11:
2348       return "movq\t{%1, %0|%0, %1}";
2350     default:
2351       gcc_unreachable ();
2352     }
2354   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2355    (set (attr "mode")
2356         (cond [(eq_attr "alternative" "3,4,9,10")
2357                  (const_string "SI")
2358                (eq_attr "alternative" "5")
2359                  (if_then_else
2360                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2361                                  (const_int 0))
2362                              (ne (symbol_ref "TARGET_SSE2")
2363                                  (const_int 0)))
2364                         (eq (symbol_ref "optimize_size")
2365                             (const_int 0)))
2366                    (const_string "TI")
2367                    (const_string "V4SF"))
2368                /* For architectures resolving dependencies on
2369                   whole SSE registers use APS move to break dependency
2370                   chains, otherwise use short move to avoid extra work.
2372                   Do the same for architectures resolving dependencies on
2373                   the parts.  While in DF mode it is better to always handle
2374                   just register parts, the SF mode is different due to lack
2375                   of instructions to load just part of the register.  It is
2376                   better to maintain the whole registers in single format
2377                   to avoid problems on using packed logical operations.  */
2378                (eq_attr "alternative" "6")
2379                  (if_then_else
2380                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2381                             (const_int 0))
2382                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2383                             (const_int 0)))
2384                    (const_string "V4SF")
2385                    (const_string "SF"))
2386                (eq_attr "alternative" "11")
2387                  (const_string "DI")]
2388                (const_string "SF")))])
2390 (define_insn "*swapsf"
2391   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2392         (match_operand:SF 1 "fp_register_operand" "+f"))
2393    (set (match_dup 1)
2394         (match_dup 0))]
2395   "reload_completed || TARGET_80387"
2397   if (STACK_TOP_P (operands[0]))
2398     return "fxch\t%1";
2399   else
2400     return "fxch\t%0";
2402   [(set_attr "type" "fxch")
2403    (set_attr "mode" "SF")])
2405 (define_expand "movdf"
2406   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2407         (match_operand:DF 1 "general_operand" ""))]
2408   ""
2409   "ix86_expand_move (DFmode, operands); DONE;")
2411 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2412 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2413 ;; On the average, pushdf using integers can be still shorter.  Allow this
2414 ;; pattern for optimize_size too.
2416 (define_insn "*pushdf_nointeger"
2417   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2418         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2419   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2421   /* This insn should be already split before reg-stack.  */
2422   gcc_unreachable ();
2424   [(set_attr "type" "multi")
2425    (set_attr "unit" "i387,*,*,*")
2426    (set_attr "mode" "DF,SI,SI,DF")])
2428 (define_insn "*pushdf_integer"
2429   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2430         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2431   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2433   /* This insn should be already split before reg-stack.  */
2434   gcc_unreachable ();
2436   [(set_attr "type" "multi")
2437    (set_attr "unit" "i387,*,*")
2438    (set_attr "mode" "DF,SI,DF")])
2440 ;; %%% Kill this when call knows how to work this out.
2441 (define_split
2442   [(set (match_operand:DF 0 "push_operand" "")
2443         (match_operand:DF 1 "any_fp_register_operand" ""))]
2444   "!TARGET_64BIT && reload_completed"
2445   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2446    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2447   "")
2449 (define_split
2450   [(set (match_operand:DF 0 "push_operand" "")
2451         (match_operand:DF 1 "any_fp_register_operand" ""))]
2452   "TARGET_64BIT && reload_completed"
2453   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2454    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2455   "")
2457 (define_split
2458   [(set (match_operand:DF 0 "push_operand" "")
2459         (match_operand:DF 1 "general_operand" ""))]
2460   "reload_completed"
2461   [(const_int 0)]
2462   "ix86_split_long_move (operands); DONE;")
2464 ;; Moving is usually shorter when only FP registers are used. This separate
2465 ;; movdf pattern avoids the use of integer registers for FP operations
2466 ;; when optimizing for size.
2468 (define_insn "*movdf_nointeger"
2469   [(set (match_operand:DF 0 "nonimmediate_operand"
2470                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2471         (match_operand:DF 1 "general_operand"
2472                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2473   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2474    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2475    && (reload_in_progress || reload_completed
2476        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2477        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2478            && standard_80387_constant_p (operands[1]))
2479        || GET_CODE (operands[1]) != CONST_DOUBLE
2480        || memory_operand (operands[0], DFmode))"
2482   switch (which_alternative)
2483     {
2484     case 0:
2485       return output_387_reg_move (insn, operands);
2487     case 1:
2488       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2489         return "fstp%z0\t%y0";
2490       else
2491         return "fst%z0\t%y0";
2493     case 2:
2494       return standard_80387_constant_opcode (operands[1]);
2496     case 3:
2497     case 4:
2498       return "#";
2499     case 5:
2500       switch (get_attr_mode (insn))
2501         {
2502         case MODE_V4SF:
2503           return "xorps\t%0, %0";
2504         case MODE_V2DF:
2505           return "xorpd\t%0, %0";
2506         case MODE_TI:
2507           return "pxor\t%0, %0";
2508         default:
2509           gcc_unreachable ();
2510         }
2511     case 6:
2512     case 7:
2513     case 8:
2514       switch (get_attr_mode (insn))
2515         {
2516         case MODE_V4SF:
2517           return "movaps\t{%1, %0|%0, %1}";
2518         case MODE_V2DF:
2519           return "movapd\t{%1, %0|%0, %1}";
2520         case MODE_TI:
2521           return "movdqa\t{%1, %0|%0, %1}";
2522         case MODE_DI:
2523           return "movq\t{%1, %0|%0, %1}";
2524         case MODE_DF:
2525           return "movsd\t{%1, %0|%0, %1}";
2526         case MODE_V1DF:
2527           return "movlpd\t{%1, %0|%0, %1}";
2528         case MODE_V2SF:
2529           return "movlps\t{%1, %0|%0, %1}";
2530         default:
2531           gcc_unreachable ();
2532         }
2534     default:
2535       gcc_unreachable ();
2536     }
2538   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2539    (set (attr "mode")
2540         (cond [(eq_attr "alternative" "0,1,2")
2541                  (const_string "DF")
2542                (eq_attr "alternative" "3,4")
2543                  (const_string "SI")
2545                /* For SSE1, we have many fewer alternatives.  */
2546                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2547                  (cond [(eq_attr "alternative" "5,6")
2548                           (const_string "V4SF")
2549                        ]
2550                    (const_string "V2SF"))
2552                /* xorps is one byte shorter.  */
2553                (eq_attr "alternative" "5")
2554                  (cond [(ne (symbol_ref "optimize_size")
2555                             (const_int 0))
2556                           (const_string "V4SF")
2557                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2558                             (const_int 0))
2559                           (const_string "TI")
2560                        ]
2561                        (const_string "V2DF"))
2563                /* For architectures resolving dependencies on
2564                   whole SSE registers use APD move to break dependency
2565                   chains, otherwise use short move to avoid extra work.
2567                   movaps encodes one byte shorter.  */
2568                (eq_attr "alternative" "6")
2569                  (cond
2570                    [(ne (symbol_ref "optimize_size")
2571                         (const_int 0))
2572                       (const_string "V4SF")
2573                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2574                         (const_int 0))
2575                       (const_string "V2DF")
2576                    ]
2577                    (const_string "DF"))
2578                /* For architectures resolving dependencies on register
2579                   parts we may avoid extra work to zero out upper part
2580                   of register.  */
2581                (eq_attr "alternative" "7")
2582                  (if_then_else
2583                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2584                        (const_int 0))
2585                    (const_string "V1DF")
2586                    (const_string "DF"))
2587               ]
2588               (const_string "DF")))])
2590 (define_insn "*movdf_integer"
2591   [(set (match_operand:DF 0 "nonimmediate_operand"
2592                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2593         (match_operand:DF 1 "general_operand"
2594                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2595   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2596    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2597    && (reload_in_progress || reload_completed
2598        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2599        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2600            && standard_80387_constant_p (operands[1]))
2601        || GET_CODE (operands[1]) != CONST_DOUBLE
2602        || memory_operand (operands[0], DFmode))"
2604   switch (which_alternative)
2605     {
2606     case 0:
2607       return output_387_reg_move (insn, operands);
2609     case 1:
2610       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2611         return "fstp%z0\t%y0";
2612       else
2613         return "fst%z0\t%y0";
2615     case 2:
2616       return standard_80387_constant_opcode (operands[1]);
2618     case 3:
2619     case 4:
2620       return "#";
2622     case 5:
2623       switch (get_attr_mode (insn))
2624         {
2625         case MODE_V4SF:
2626           return "xorps\t%0, %0";
2627         case MODE_V2DF:
2628           return "xorpd\t%0, %0";
2629         case MODE_TI:
2630           return "pxor\t%0, %0";
2631         default:
2632           gcc_unreachable ();
2633         }
2634     case 6:
2635     case 7:
2636     case 8:
2637       switch (get_attr_mode (insn))
2638         {
2639         case MODE_V4SF:
2640           return "movaps\t{%1, %0|%0, %1}";
2641         case MODE_V2DF:
2642           return "movapd\t{%1, %0|%0, %1}";
2643         case MODE_TI:
2644           return "movdqa\t{%1, %0|%0, %1}";
2645         case MODE_DI:
2646           return "movq\t{%1, %0|%0, %1}";
2647         case MODE_DF:
2648           return "movsd\t{%1, %0|%0, %1}";
2649         case MODE_V1DF:
2650           return "movlpd\t{%1, %0|%0, %1}";
2651         case MODE_V2SF:
2652           return "movlps\t{%1, %0|%0, %1}";
2653         default:
2654           gcc_unreachable ();
2655         }
2657     default:
2658       gcc_unreachable();
2659     }
2661   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2662    (set (attr "mode")
2663         (cond [(eq_attr "alternative" "0,1,2")
2664                  (const_string "DF")
2665                (eq_attr "alternative" "3,4")
2666                  (const_string "SI")
2668                /* For SSE1, we have many fewer alternatives.  */
2669                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2670                  (cond [(eq_attr "alternative" "5,6")
2671                           (const_string "V4SF")
2672                        ]
2673                    (const_string "V2SF"))
2675                /* xorps is one byte shorter.  */
2676                (eq_attr "alternative" "5")
2677                  (cond [(ne (symbol_ref "optimize_size")
2678                             (const_int 0))
2679                           (const_string "V4SF")
2680                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2681                             (const_int 0))
2682                           (const_string "TI")
2683                        ]
2684                        (const_string "V2DF"))
2686                /* For architectures resolving dependencies on
2687                   whole SSE registers use APD move to break dependency
2688                   chains, otherwise use short move to avoid extra work.
2690                   movaps encodes one byte shorter.  */
2691                (eq_attr "alternative" "6")
2692                  (cond
2693                    [(ne (symbol_ref "optimize_size")
2694                         (const_int 0))
2695                       (const_string "V4SF")
2696                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2697                         (const_int 0))
2698                       (const_string "V2DF")
2699                    ]
2700                    (const_string "DF"))
2701                /* For architectures resolving dependencies on register
2702                   parts we may avoid extra work to zero out upper part
2703                   of register.  */
2704                (eq_attr "alternative" "7")
2705                  (if_then_else
2706                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2707                        (const_int 0))
2708                    (const_string "V1DF")
2709                    (const_string "DF"))
2710               ]
2711               (const_string "DF")))])
2713 (define_split
2714   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2715         (match_operand:DF 1 "general_operand" ""))]
2716   "reload_completed
2717    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2718    && ! (ANY_FP_REG_P (operands[0]) ||
2719          (GET_CODE (operands[0]) == SUBREG
2720           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2721    && ! (ANY_FP_REG_P (operands[1]) ||
2722          (GET_CODE (operands[1]) == SUBREG
2723           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2724   [(const_int 0)]
2725   "ix86_split_long_move (operands); DONE;")
2727 (define_insn "*swapdf"
2728   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2729         (match_operand:DF 1 "fp_register_operand" "+f"))
2730    (set (match_dup 1)
2731         (match_dup 0))]
2732   "reload_completed || TARGET_80387"
2734   if (STACK_TOP_P (operands[0]))
2735     return "fxch\t%1";
2736   else
2737     return "fxch\t%0";
2739   [(set_attr "type" "fxch")
2740    (set_attr "mode" "DF")])
2742 (define_expand "movxf"
2743   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2744         (match_operand:XF 1 "general_operand" ""))]
2745   ""
2746   "ix86_expand_move (XFmode, operands); DONE;")
2748 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2749 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2750 ;; Pushing using integer instructions is longer except for constants
2751 ;; and direct memory references.
2752 ;; (assuming that any given constant is pushed only once, but this ought to be
2753 ;;  handled elsewhere).
2755 (define_insn "*pushxf_nointeger"
2756   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2757         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2758   "optimize_size"
2760   /* This insn should be already split before reg-stack.  */
2761   gcc_unreachable ();
2763   [(set_attr "type" "multi")
2764    (set_attr "unit" "i387,*,*")
2765    (set_attr "mode" "XF,SI,SI")])
2767 (define_insn "*pushxf_integer"
2768   [(set (match_operand:XF 0 "push_operand" "=<,<")
2769         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2770   "!optimize_size"
2772   /* This insn should be already split before reg-stack.  */
2773   gcc_unreachable ();
2775   [(set_attr "type" "multi")
2776    (set_attr "unit" "i387,*")
2777    (set_attr "mode" "XF,SI")])
2779 (define_split
2780   [(set (match_operand 0 "push_operand" "")
2781         (match_operand 1 "general_operand" ""))]
2782   "reload_completed
2783    && (GET_MODE (operands[0]) == XFmode
2784        || GET_MODE (operands[0]) == DFmode)
2785    && !ANY_FP_REG_P (operands[1])"
2786   [(const_int 0)]
2787   "ix86_split_long_move (operands); DONE;")
2789 (define_split
2790   [(set (match_operand:XF 0 "push_operand" "")
2791         (match_operand:XF 1 "any_fp_register_operand" ""))]
2792   "!TARGET_64BIT"
2793   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2794    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2795   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2797 (define_split
2798   [(set (match_operand:XF 0 "push_operand" "")
2799         (match_operand:XF 1 "any_fp_register_operand" ""))]
2800   "TARGET_64BIT"
2801   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2802    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2803   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2805 ;; Do not use integer registers when optimizing for size
2806 (define_insn "*movxf_nointeger"
2807   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2808         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2809   "optimize_size
2810    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2811    && (reload_in_progress || reload_completed
2812        || (optimize_size && standard_80387_constant_p (operands[1]))
2813        || GET_CODE (operands[1]) != CONST_DOUBLE
2814        || memory_operand (operands[0], XFmode))"
2816   switch (which_alternative)
2817     {
2818     case 0:
2819       return output_387_reg_move (insn, operands);
2821     case 1:
2822       /* There is no non-popping store to memory for XFmode.  So if
2823          we need one, follow the store with a load.  */
2824       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2825         return "fstp%z0\t%y0\;fld%z0\t%y0";
2826       else
2827         return "fstp%z0\t%y0";
2829     case 2:
2830       return standard_80387_constant_opcode (operands[1]);
2832     case 3: case 4:
2833       return "#";
2834     default:
2835       gcc_unreachable ();
2836     }
2838   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839    (set_attr "mode" "XF,XF,XF,SI,SI")])
2841 (define_insn "*movxf_integer"
2842   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2843         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2844   "!optimize_size
2845    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2846    && (reload_in_progress || reload_completed
2847        || (optimize_size && standard_80387_constant_p (operands[1]))
2848        || GET_CODE (operands[1]) != CONST_DOUBLE
2849        || memory_operand (operands[0], XFmode))"
2851   switch (which_alternative)
2852     {
2853     case 0:
2854       return output_387_reg_move (insn, operands);
2856     case 1:
2857       /* There is no non-popping store to memory for XFmode.  So if
2858          we need one, follow the store with a load.  */
2859       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2860         return "fstp%z0\t%y0\;fld%z0\t%y0";
2861       else
2862         return "fstp%z0\t%y0";
2864     case 2:
2865       return standard_80387_constant_opcode (operands[1]);
2867     case 3: case 4:
2868       return "#";
2870     default:
2871       gcc_unreachable ();
2872     }
2874   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2875    (set_attr "mode" "XF,XF,XF,SI,SI")])
2877 (define_split
2878   [(set (match_operand 0 "nonimmediate_operand" "")
2879         (match_operand 1 "general_operand" ""))]
2880   "reload_completed
2881    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2882    && GET_MODE (operands[0]) == XFmode
2883    && ! (ANY_FP_REG_P (operands[0]) ||
2884          (GET_CODE (operands[0]) == SUBREG
2885           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2886    && ! (ANY_FP_REG_P (operands[1]) ||
2887          (GET_CODE (operands[1]) == SUBREG
2888           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2889   [(const_int 0)]
2890   "ix86_split_long_move (operands); DONE;")
2892 (define_split
2893   [(set (match_operand 0 "register_operand" "")
2894         (match_operand 1 "memory_operand" ""))]
2895   "reload_completed
2896    && MEM_P (operands[1])
2897    && (GET_MODE (operands[0]) == XFmode
2898        || GET_MODE (operands[0]) == SFmode
2899        || GET_MODE (operands[0]) == DFmode)
2900    && constant_pool_reference_p (operands[1])"
2901   [(set (match_dup 0) (match_dup 1))]
2903   rtx c = avoid_constant_pool_reference (operands[1]);
2904   rtx r = operands[0];
2906   if (GET_CODE (r) == SUBREG)
2907     r = SUBREG_REG (r);
2909   if (SSE_REG_P (r))
2910     {
2911       if (!standard_sse_constant_p (c))
2912         FAIL;
2913     }
2914   else if (FP_REG_P (r))
2915     {
2916       if (!standard_80387_constant_p (c))
2917         FAIL;
2918     }
2919   else if (MMX_REG_P (r))
2920     FAIL;
2922   operands[1] = c;
2925 (define_split
2926   [(set (match_operand 0 "register_operand" "")
2927         (float_extend (match_operand 1 "memory_operand" "")))]
2928   "reload_completed
2929    && MEM_P (operands[1])
2930    && (GET_MODE (operands[0]) == XFmode
2931        || GET_MODE (operands[0]) == SFmode
2932        || GET_MODE (operands[0]) == DFmode)
2933    && constant_pool_reference_p (operands[1])"
2934   [(set (match_dup 0) (match_dup 1))]
2936   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2937   rtx r = operands[0];
2939   if (GET_CODE (r) == SUBREG)
2940     r = SUBREG_REG (r);
2942   if (SSE_REG_P (r))
2943     {
2944       if (!standard_sse_constant_p (c))
2945         FAIL;
2946     }
2947   else if (FP_REG_P (r))
2948     {
2949       if (!standard_80387_constant_p (c))
2950         FAIL;
2951     }
2952   else if (MMX_REG_P (r))
2953     FAIL;
2955   operands[1] = c;
2958 (define_insn "swapxf"
2959   [(set (match_operand:XF 0 "register_operand" "+f")
2960         (match_operand:XF 1 "register_operand" "+f"))
2961    (set (match_dup 1)
2962         (match_dup 0))]
2963   "TARGET_80387"
2965   if (STACK_TOP_P (operands[0]))
2966     return "fxch\t%1";
2967   else
2968     return "fxch\t%0";
2970   [(set_attr "type" "fxch")
2971    (set_attr "mode" "XF")])
2973 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2974 (define_split
2975   [(set (match_operand:X87MODEF 0 "register_operand" "")
2976         (match_operand:X87MODEF 1 "immediate_operand" ""))]
2977   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2978    && (standard_80387_constant_p (operands[1]) == 8
2979        || standard_80387_constant_p (operands[1]) == 9)"
2980   [(set (match_dup 0)(match_dup 1))
2981    (set (match_dup 0)
2982         (neg:X87MODEF (match_dup 0)))]
2984   REAL_VALUE_TYPE r;
2986   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2987   if (real_isnegzero (&r))
2988     operands[1] = CONST0_RTX (<MODE>mode);
2989   else
2990     operands[1] = CONST1_RTX (<MODE>mode);
2993 (define_expand "movtf"
2994   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2995         (match_operand:TF 1 "nonimmediate_operand" ""))]
2996   "TARGET_64BIT"
2998   ix86_expand_move (TFmode, operands);
2999   DONE;
3002 (define_insn "*movtf_internal"
3003   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3004         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3005   "TARGET_64BIT
3006    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3008   switch (which_alternative)
3009     {
3010     case 0:
3011     case 1:
3012       return "#";
3013     case 2:
3014       if (get_attr_mode (insn) == MODE_V4SF)
3015         return "xorps\t%0, %0";
3016       else
3017         return "pxor\t%0, %0";
3018     case 3:
3019     case 4:
3020       if (get_attr_mode (insn) == MODE_V4SF)
3021         return "movaps\t{%1, %0|%0, %1}";
3022       else
3023         return "movdqa\t{%1, %0|%0, %1}";
3024     default:
3025       gcc_unreachable ();
3026     }
3028   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3029    (set (attr "mode")
3030         (cond [(eq_attr "alternative" "2,3")
3031                  (if_then_else
3032                    (ne (symbol_ref "optimize_size")
3033                        (const_int 0))
3034                    (const_string "V4SF")
3035                    (const_string "TI"))
3036                (eq_attr "alternative" "4")
3037                  (if_then_else
3038                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3039                             (const_int 0))
3040                         (ne (symbol_ref "optimize_size")
3041                             (const_int 0)))
3042                    (const_string "V4SF")
3043                    (const_string "TI"))]
3044                (const_string "DI")))])
3046 (define_split
3047   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3048         (match_operand:TF 1 "general_operand" ""))]
3049   "reload_completed && !SSE_REG_P (operands[0])
3050    && !SSE_REG_P (operands[1])"
3051   [(const_int 0)]
3052   "ix86_split_long_move (operands); DONE;")
3054 ;; Zero extension instructions
3056 (define_expand "zero_extendhisi2"
3057   [(set (match_operand:SI 0 "register_operand" "")
3058      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3059   ""
3061   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3062     {
3063       operands[1] = force_reg (HImode, operands[1]);
3064       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3065       DONE;
3066     }
3069 (define_insn "zero_extendhisi2_and"
3070   [(set (match_operand:SI 0 "register_operand" "=r")
3071      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3074   "#"
3075   [(set_attr "type" "alu1")
3076    (set_attr "mode" "SI")])
3078 (define_split
3079   [(set (match_operand:SI 0 "register_operand" "")
3080         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3081    (clobber (reg:CC FLAGS_REG))]
3082   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3083   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3084               (clobber (reg:CC FLAGS_REG))])]
3085   "")
3087 (define_insn "*zero_extendhisi2_movzwl"
3088   [(set (match_operand:SI 0 "register_operand" "=r")
3089      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3090   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3091   "movz{wl|x}\t{%1, %0|%0, %1}"
3092   [(set_attr "type" "imovx")
3093    (set_attr "mode" "SI")])
3095 (define_expand "zero_extendqihi2"
3096   [(parallel
3097     [(set (match_operand:HI 0 "register_operand" "")
3098        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3099      (clobber (reg:CC FLAGS_REG))])]
3100   ""
3101   "")
3103 (define_insn "*zero_extendqihi2_and"
3104   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3105      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3106    (clobber (reg:CC FLAGS_REG))]
3107   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3108   "#"
3109   [(set_attr "type" "alu1")
3110    (set_attr "mode" "HI")])
3112 (define_insn "*zero_extendqihi2_movzbw_and"
3113   [(set (match_operand:HI 0 "register_operand" "=r,r")
3114      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3115    (clobber (reg:CC FLAGS_REG))]
3116   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3117   "#"
3118   [(set_attr "type" "imovx,alu1")
3119    (set_attr "mode" "HI")])
3121 ; zero extend to SImode here to avoid partial register stalls
3122 (define_insn "*zero_extendqihi2_movzbl"
3123   [(set (match_operand:HI 0 "register_operand" "=r")
3124      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3125   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3126   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3127   [(set_attr "type" "imovx")
3128    (set_attr "mode" "SI")])
3130 ;; For the movzbw case strip only the clobber
3131 (define_split
3132   [(set (match_operand:HI 0 "register_operand" "")
3133         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3134    (clobber (reg:CC FLAGS_REG))]
3135   "reload_completed
3136    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3137    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3138   [(set (match_operand:HI 0 "register_operand" "")
3139         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3141 ;; When source and destination does not overlap, clear destination
3142 ;; first and then do the movb
3143 (define_split
3144   [(set (match_operand:HI 0 "register_operand" "")
3145         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3146    (clobber (reg:CC FLAGS_REG))]
3147   "reload_completed
3148    && ANY_QI_REG_P (operands[0])
3149    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3150    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3151   [(set (match_dup 0) (const_int 0))
3152    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3153   "operands[2] = gen_lowpart (QImode, operands[0]);")
3155 ;; Rest is handled by single and.
3156 (define_split
3157   [(set (match_operand:HI 0 "register_operand" "")
3158         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3159    (clobber (reg:CC FLAGS_REG))]
3160   "reload_completed
3161    && true_regnum (operands[0]) == true_regnum (operands[1])"
3162   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3163               (clobber (reg:CC FLAGS_REG))])]
3164   "")
3166 (define_expand "zero_extendqisi2"
3167   [(parallel
3168     [(set (match_operand:SI 0 "register_operand" "")
3169        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3170      (clobber (reg:CC FLAGS_REG))])]
3171   ""
3172   "")
3174 (define_insn "*zero_extendqisi2_and"
3175   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3176      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3177    (clobber (reg:CC FLAGS_REG))]
3178   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3179   "#"
3180   [(set_attr "type" "alu1")
3181    (set_attr "mode" "SI")])
3183 (define_insn "*zero_extendqisi2_movzbw_and"
3184   [(set (match_operand:SI 0 "register_operand" "=r,r")
3185      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3186    (clobber (reg:CC FLAGS_REG))]
3187   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3188   "#"
3189   [(set_attr "type" "imovx,alu1")
3190    (set_attr "mode" "SI")])
3192 (define_insn "*zero_extendqisi2_movzbw"
3193   [(set (match_operand:SI 0 "register_operand" "=r")
3194      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3195   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3196   "movz{bl|x}\t{%1, %0|%0, %1}"
3197   [(set_attr "type" "imovx")
3198    (set_attr "mode" "SI")])
3200 ;; For the movzbl case strip only the clobber
3201 (define_split
3202   [(set (match_operand:SI 0 "register_operand" "")
3203         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3204    (clobber (reg:CC FLAGS_REG))]
3205   "reload_completed
3206    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3207    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3208   [(set (match_dup 0)
3209         (zero_extend:SI (match_dup 1)))])
3211 ;; When source and destination does not overlap, clear destination
3212 ;; first and then do the movb
3213 (define_split
3214   [(set (match_operand:SI 0 "register_operand" "")
3215         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3216    (clobber (reg:CC FLAGS_REG))]
3217   "reload_completed
3218    && ANY_QI_REG_P (operands[0])
3219    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3220    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3221    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3222   [(set (match_dup 0) (const_int 0))
3223    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3224   "operands[2] = gen_lowpart (QImode, operands[0]);")
3226 ;; Rest is handled by single and.
3227 (define_split
3228   [(set (match_operand:SI 0 "register_operand" "")
3229         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3230    (clobber (reg:CC FLAGS_REG))]
3231   "reload_completed
3232    && true_regnum (operands[0]) == true_regnum (operands[1])"
3233   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3234               (clobber (reg:CC FLAGS_REG))])]
3235   "")
3237 ;; %%% Kill me once multi-word ops are sane.
3238 (define_expand "zero_extendsidi2"
3239   [(set (match_operand:DI 0 "register_operand" "=r")
3240      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3241   ""
3242   "if (!TARGET_64BIT)
3243      {
3244        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3245        DONE;
3246      }
3247   ")
3249 (define_insn "zero_extendsidi2_32"
3250   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3251         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3252    (clobber (reg:CC FLAGS_REG))]
3253   "!TARGET_64BIT"
3254   "@
3255    #
3256    #
3257    #
3258    movd\t{%1, %0|%0, %1}
3259    movd\t{%1, %0|%0, %1}"
3260   [(set_attr "mode" "SI,SI,SI,DI,TI")
3261    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3263 (define_insn "zero_extendsidi2_rex64"
3264   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3265      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3266   "TARGET_64BIT"
3267   "@
3268    mov\t{%k1, %k0|%k0, %k1}
3269    #
3270    movd\t{%1, %0|%0, %1}
3271    movd\t{%1, %0|%0, %1}"
3272   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3273    (set_attr "mode" "SI,DI,SI,SI")])
3275 (define_split
3276   [(set (match_operand:DI 0 "memory_operand" "")
3277      (zero_extend:DI (match_dup 0)))]
3278   "TARGET_64BIT"
3279   [(set (match_dup 4) (const_int 0))]
3280   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3282 (define_split
3283   [(set (match_operand:DI 0 "register_operand" "")
3284         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3285    (clobber (reg:CC FLAGS_REG))]
3286   "!TARGET_64BIT && reload_completed
3287    && true_regnum (operands[0]) == true_regnum (operands[1])"
3288   [(set (match_dup 4) (const_int 0))]
3289   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3291 (define_split
3292   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3293         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3294    (clobber (reg:CC FLAGS_REG))]
3295   "!TARGET_64BIT && reload_completed
3296    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3297   [(set (match_dup 3) (match_dup 1))
3298    (set (match_dup 4) (const_int 0))]
3299   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3301 (define_insn "zero_extendhidi2"
3302   [(set (match_operand:DI 0 "register_operand" "=r")
3303      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3304   "TARGET_64BIT"
3305   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3306   [(set_attr "type" "imovx")
3307    (set_attr "mode" "DI")])
3309 (define_insn "zero_extendqidi2"
3310   [(set (match_operand:DI 0 "register_operand" "=r")
3311      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3312   "TARGET_64BIT"
3313   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3314   [(set_attr "type" "imovx")
3315    (set_attr "mode" "DI")])
3317 ;; Sign extension instructions
3319 (define_expand "extendsidi2"
3320   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3321                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3322               (clobber (reg:CC FLAGS_REG))
3323               (clobber (match_scratch:SI 2 ""))])]
3324   ""
3326   if (TARGET_64BIT)
3327     {
3328       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3329       DONE;
3330     }
3333 (define_insn "*extendsidi2_1"
3334   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3335         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3336    (clobber (reg:CC FLAGS_REG))
3337    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3338   "!TARGET_64BIT"
3339   "#")
3341 (define_insn "extendsidi2_rex64"
3342   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3343         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3344   "TARGET_64BIT"
3345   "@
3346    {cltq|cdqe}
3347    movs{lq|x}\t{%1,%0|%0, %1}"
3348   [(set_attr "type" "imovx")
3349    (set_attr "mode" "DI")
3350    (set_attr "prefix_0f" "0")
3351    (set_attr "modrm" "0,1")])
3353 (define_insn "extendhidi2"
3354   [(set (match_operand:DI 0 "register_operand" "=r")
3355         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3356   "TARGET_64BIT"
3357   "movs{wq|x}\t{%1,%0|%0, %1}"
3358   [(set_attr "type" "imovx")
3359    (set_attr "mode" "DI")])
3361 (define_insn "extendqidi2"
3362   [(set (match_operand:DI 0 "register_operand" "=r")
3363         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3364   "TARGET_64BIT"
3365   "movs{bq|x}\t{%1,%0|%0, %1}"
3366    [(set_attr "type" "imovx")
3367     (set_attr "mode" "DI")])
3369 ;; Extend to memory case when source register does die.
3370 (define_split
3371   [(set (match_operand:DI 0 "memory_operand" "")
3372         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3373    (clobber (reg:CC FLAGS_REG))
3374    (clobber (match_operand:SI 2 "register_operand" ""))]
3375   "(reload_completed
3376     && dead_or_set_p (insn, operands[1])
3377     && !reg_mentioned_p (operands[1], operands[0]))"
3378   [(set (match_dup 3) (match_dup 1))
3379    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3380               (clobber (reg:CC FLAGS_REG))])
3381    (set (match_dup 4) (match_dup 1))]
3382   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3384 ;; Extend to memory case when source register does not die.
3385 (define_split
3386   [(set (match_operand:DI 0 "memory_operand" "")
3387         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3388    (clobber (reg:CC FLAGS_REG))
3389    (clobber (match_operand:SI 2 "register_operand" ""))]
3390   "reload_completed"
3391   [(const_int 0)]
3393   split_di (&operands[0], 1, &operands[3], &operands[4]);
3395   emit_move_insn (operands[3], operands[1]);
3397   /* Generate a cltd if possible and doing so it profitable.  */
3398   if (true_regnum (operands[1]) == 0
3399       && true_regnum (operands[2]) == 1
3400       && (optimize_size || TARGET_USE_CLTD))
3401     {
3402       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3403     }
3404   else
3405     {
3406       emit_move_insn (operands[2], operands[1]);
3407       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3408     }
3409   emit_move_insn (operands[4], operands[2]);
3410   DONE;
3413 ;; Extend to register case.  Optimize case where source and destination
3414 ;; registers match and cases where we can use cltd.
3415 (define_split
3416   [(set (match_operand:DI 0 "register_operand" "")
3417         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3418    (clobber (reg:CC FLAGS_REG))
3419    (clobber (match_scratch:SI 2 ""))]
3420   "reload_completed"
3421   [(const_int 0)]
3423   split_di (&operands[0], 1, &operands[3], &operands[4]);
3425   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3426     emit_move_insn (operands[3], operands[1]);
3428   /* Generate a cltd if possible and doing so it profitable.  */
3429   if (true_regnum (operands[3]) == 0
3430       && (optimize_size || TARGET_USE_CLTD))
3431     {
3432       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3433       DONE;
3434     }
3436   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3437     emit_move_insn (operands[4], operands[1]);
3439   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3440   DONE;
3443 (define_insn "extendhisi2"
3444   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3445         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3446   ""
3448   switch (get_attr_prefix_0f (insn))
3449     {
3450     case 0:
3451       return "{cwtl|cwde}";
3452     default:
3453       return "movs{wl|x}\t{%1,%0|%0, %1}";
3454     }
3456   [(set_attr "type" "imovx")
3457    (set_attr "mode" "SI")
3458    (set (attr "prefix_0f")
3459      ;; movsx is short decodable while cwtl is vector decoded.
3460      (if_then_else (and (eq_attr "cpu" "!k6")
3461                         (eq_attr "alternative" "0"))
3462         (const_string "0")
3463         (const_string "1")))
3464    (set (attr "modrm")
3465      (if_then_else (eq_attr "prefix_0f" "0")
3466         (const_string "0")
3467         (const_string "1")))])
3469 (define_insn "*extendhisi2_zext"
3470   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3471         (zero_extend:DI
3472           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3473   "TARGET_64BIT"
3475   switch (get_attr_prefix_0f (insn))
3476     {
3477     case 0:
3478       return "{cwtl|cwde}";
3479     default:
3480       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3481     }
3483   [(set_attr "type" "imovx")
3484    (set_attr "mode" "SI")
3485    (set (attr "prefix_0f")
3486      ;; movsx is short decodable while cwtl is vector decoded.
3487      (if_then_else (and (eq_attr "cpu" "!k6")
3488                         (eq_attr "alternative" "0"))
3489         (const_string "0")
3490         (const_string "1")))
3491    (set (attr "modrm")
3492      (if_then_else (eq_attr "prefix_0f" "0")
3493         (const_string "0")
3494         (const_string "1")))])
3496 (define_insn "extendqihi2"
3497   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3498         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3499   ""
3501   switch (get_attr_prefix_0f (insn))
3502     {
3503     case 0:
3504       return "{cbtw|cbw}";
3505     default:
3506       return "movs{bw|x}\t{%1,%0|%0, %1}";
3507     }
3509   [(set_attr "type" "imovx")
3510    (set_attr "mode" "HI")
3511    (set (attr "prefix_0f")
3512      ;; movsx is short decodable while cwtl is vector decoded.
3513      (if_then_else (and (eq_attr "cpu" "!k6")
3514                         (eq_attr "alternative" "0"))
3515         (const_string "0")
3516         (const_string "1")))
3517    (set (attr "modrm")
3518      (if_then_else (eq_attr "prefix_0f" "0")
3519         (const_string "0")
3520         (const_string "1")))])
3522 (define_insn "extendqisi2"
3523   [(set (match_operand:SI 0 "register_operand" "=r")
3524         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3525   ""
3526   "movs{bl|x}\t{%1,%0|%0, %1}"
3527    [(set_attr "type" "imovx")
3528     (set_attr "mode" "SI")])
3530 (define_insn "*extendqisi2_zext"
3531   [(set (match_operand:DI 0 "register_operand" "=r")
3532         (zero_extend:DI
3533           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3534   "TARGET_64BIT"
3535   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3536    [(set_attr "type" "imovx")
3537     (set_attr "mode" "SI")])
3539 ;; Conversions between float and double.
3541 ;; These are all no-ops in the model used for the 80387.  So just
3542 ;; emit moves.
3544 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3545 (define_insn "*dummy_extendsfdf2"
3546   [(set (match_operand:DF 0 "push_operand" "=<")
3547         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3548   "0"
3549   "#")
3551 (define_split
3552   [(set (match_operand:DF 0 "push_operand" "")
3553         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3554   "!TARGET_64BIT"
3555   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3556    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3558 (define_split
3559   [(set (match_operand:DF 0 "push_operand" "")
3560         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3561   "TARGET_64BIT"
3562   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3563    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3565 (define_insn "*dummy_extendsfxf2"
3566   [(set (match_operand:XF 0 "push_operand" "=<")
3567         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3568   "0"
3569   "#")
3571 (define_split
3572   [(set (match_operand:XF 0 "push_operand" "")
3573         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3574   ""
3575   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3576    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3577   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3579 (define_split
3580   [(set (match_operand:XF 0 "push_operand" "")
3581         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3582   "TARGET_64BIT"
3583   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3584    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3585   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3587 (define_split
3588   [(set (match_operand:XF 0 "push_operand" "")
3589         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3590   ""
3591   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3592    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3593   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3595 (define_split
3596   [(set (match_operand:XF 0 "push_operand" "")
3597         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3598   "TARGET_64BIT"
3599   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3600    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3601   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3603 (define_expand "extendsfdf2"
3604   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3605         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3606   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3608   /* ??? Needed for compress_float_constant since all fp constants
3609      are LEGITIMATE_CONSTANT_P.  */
3610   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3611     {
3612       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3613           && standard_80387_constant_p (operands[1]) > 0)
3614         {
3615           operands[1] = simplify_const_unary_operation
3616             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3617           emit_move_insn_1 (operands[0], operands[1]);
3618           DONE;
3619         }
3620       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3621     }
3624 (define_insn "*extendsfdf2_mixed"
3625   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3626         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3627   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3629   switch (which_alternative)
3630     {
3631     case 0:
3632       return output_387_reg_move (insn, operands);
3634     case 1:
3635       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3636         return "fstp%z0\t%y0";
3637       else
3638         return "fst%z0\t%y0";
3640     case 2:
3641       return "cvtss2sd\t{%1, %0|%0, %1}";
3643     default:
3644       gcc_unreachable ();
3645     }
3647   [(set_attr "type" "fmov,fmov,ssecvt")
3648    (set_attr "mode" "SF,XF,DF")])
3650 (define_insn "*extendsfdf2_sse"
3651   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3652         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3653   "TARGET_SSE2 && TARGET_SSE_MATH"
3654   "cvtss2sd\t{%1, %0|%0, %1}"
3655   [(set_attr "type" "ssecvt")
3656    (set_attr "mode" "DF")])
3658 (define_insn "*extendsfdf2_i387"
3659   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3660         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3661   "TARGET_80387"
3663   switch (which_alternative)
3664     {
3665     case 0:
3666       return output_387_reg_move (insn, operands);
3668     case 1:
3669       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3670         return "fstp%z0\t%y0";
3671       else
3672         return "fst%z0\t%y0";
3674     default:
3675       gcc_unreachable ();
3676     }
3678   [(set_attr "type" "fmov")
3679    (set_attr "mode" "SF,XF")])
3681 (define_expand "extendsfxf2"
3682   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3683         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3684   "TARGET_80387"
3686   /* ??? Needed for compress_float_constant since all fp constants
3687      are LEGITIMATE_CONSTANT_P.  */
3688   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3689     {
3690       if (standard_80387_constant_p (operands[1]) > 0)
3691         {
3692           operands[1] = simplify_const_unary_operation
3693             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3694           emit_move_insn_1 (operands[0], operands[1]);
3695           DONE;
3696         }
3697       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3698     }
3701 (define_insn "*extendsfxf2_i387"
3702   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3703         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3704   "TARGET_80387"
3706   switch (which_alternative)
3707     {
3708     case 0:
3709       return output_387_reg_move (insn, operands);
3711     case 1:
3712       /* There is no non-popping store to memory for XFmode.  So if
3713          we need one, follow the store with a load.  */
3714       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3715         return "fstp%z0\t%y0";
3716       else
3717         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3719     default:
3720       gcc_unreachable ();
3721     }
3723   [(set_attr "type" "fmov")
3724    (set_attr "mode" "SF,XF")])
3726 (define_expand "extenddfxf2"
3727   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3728         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3729   "TARGET_80387"
3731   /* ??? Needed for compress_float_constant since all fp constants
3732      are LEGITIMATE_CONSTANT_P.  */
3733   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3734     {
3735       if (standard_80387_constant_p (operands[1]) > 0)
3736         {
3737           operands[1] = simplify_const_unary_operation
3738             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3739           emit_move_insn_1 (operands[0], operands[1]);
3740           DONE;
3741         }
3742       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3743     }
3746 (define_insn "*extenddfxf2_i387"
3747   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3748         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3749   "TARGET_80387"
3751   switch (which_alternative)
3752     {
3753     case 0:
3754       return output_387_reg_move (insn, operands);
3756     case 1:
3757       /* There is no non-popping store to memory for XFmode.  So if
3758          we need one, follow the store with a load.  */
3759       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3760         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3761       else
3762         return "fstp%z0\t%y0";
3764     default:
3765       gcc_unreachable ();
3766     }
3768   [(set_attr "type" "fmov")
3769    (set_attr "mode" "DF,XF")])
3771 ;; %%% This seems bad bad news.
3772 ;; This cannot output into an f-reg because there is no way to be sure
3773 ;; of truncating in that case.  Otherwise this is just like a simple move
3774 ;; insn.  So we pretend we can output to a reg in order to get better
3775 ;; register preferencing, but we really use a stack slot.
3777 ;; Conversion from DFmode to SFmode.
3779 (define_expand "truncdfsf2"
3780   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3781         (float_truncate:SF
3782           (match_operand:DF 1 "nonimmediate_operand" "")))]
3783   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3785   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3786     ;
3787   else if (flag_unsafe_math_optimizations)
3788     ;
3789   else
3790     {
3791       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3792       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3793       DONE;
3794     }
3797 (define_expand "truncdfsf2_with_temp"
3798   [(parallel [(set (match_operand:SF 0 "" "")
3799                    (float_truncate:SF (match_operand:DF 1 "" "")))
3800               (clobber (match_operand:SF 2 "" ""))])]
3801   "")
3803 (define_insn "*truncdfsf_fast_mixed"
3804   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3805         (float_truncate:SF
3806           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3807   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3809   switch (which_alternative)
3810     {
3811     case 0:
3812       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813         return "fstp%z0\t%y0";
3814       else
3815         return "fst%z0\t%y0";
3816     case 1:
3817       return output_387_reg_move (insn, operands);
3818     case 2:
3819       return "cvtsd2ss\t{%1, %0|%0, %1}";
3820     default:
3821       gcc_unreachable ();
3822     }
3824   [(set_attr "type" "fmov,fmov,ssecvt")
3825    (set_attr "mode" "SF")])
3827 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3828 ;; because nothing we do here is unsafe.
3829 (define_insn "*truncdfsf_fast_sse"
3830   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3831         (float_truncate:SF
3832           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3833   "TARGET_SSE2 && TARGET_SSE_MATH"
3834   "cvtsd2ss\t{%1, %0|%0, %1}"
3835   [(set_attr "type" "ssecvt")
3836    (set_attr "mode" "SF")])
3838 (define_insn "*truncdfsf_fast_i387"
3839   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3840         (float_truncate:SF
3841           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3842   "TARGET_80387 && flag_unsafe_math_optimizations"
3843   "* return output_387_reg_move (insn, operands);"
3844   [(set_attr "type" "fmov")
3845    (set_attr "mode" "SF")])
3847 (define_insn "*truncdfsf_mixed"
3848   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3849         (float_truncate:SF
3850           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3851    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3852   "TARGET_MIX_SSE_I387"
3854   switch (which_alternative)
3855     {
3856     case 0:
3857       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3858         return "fstp%z0\t%y0";
3859       else
3860         return "fst%z0\t%y0";
3861     case 1:
3862       return "#";
3863     case 2:
3864       return "cvtsd2ss\t{%1, %0|%0, %1}";
3865     default:
3866       gcc_unreachable ();
3867     }
3869   [(set_attr "type" "fmov,multi,ssecvt")
3870    (set_attr "unit" "*,i387,*")
3871    (set_attr "mode" "SF")])
3873 (define_insn "*truncdfsf_i387"
3874   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3875         (float_truncate:SF
3876           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3877    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3878   "TARGET_80387"
3880   switch (which_alternative)
3881     {
3882     case 0:
3883       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3884         return "fstp%z0\t%y0";
3885       else
3886         return "fst%z0\t%y0";
3887     case 1:
3888       return "#";
3889     default:
3890       gcc_unreachable ();
3891     }
3893   [(set_attr "type" "fmov,multi")
3894    (set_attr "unit" "*,i387")
3895    (set_attr "mode" "SF")])
3897 (define_insn "*truncdfsf2_i387_1"
3898   [(set (match_operand:SF 0 "memory_operand" "=m")
3899         (float_truncate:SF
3900           (match_operand:DF 1 "register_operand" "f")))]
3901   "TARGET_80387
3902    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3903    && !TARGET_MIX_SSE_I387"
3905   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3906     return "fstp%z0\t%y0";
3907   else
3908     return "fst%z0\t%y0";
3910   [(set_attr "type" "fmov")
3911    (set_attr "mode" "SF")])
3913 (define_split
3914   [(set (match_operand:SF 0 "register_operand" "")
3915         (float_truncate:SF
3916          (match_operand:DF 1 "fp_register_operand" "")))
3917    (clobber (match_operand 2 "" ""))]
3918   "reload_completed"
3919   [(set (match_dup 2) (match_dup 1))
3920    (set (match_dup 0) (match_dup 2))]
3922   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3925 ;; Conversion from XFmode to SFmode.
3927 (define_expand "truncxfsf2"
3928   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3929                    (float_truncate:SF
3930                     (match_operand:XF 1 "register_operand" "")))
3931               (clobber (match_dup 2))])]
3932   "TARGET_80387"
3934   if (flag_unsafe_math_optimizations)
3935     {
3936       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3937       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3938       if (reg != operands[0])
3939         emit_move_insn (operands[0], reg);
3940       DONE;
3941     }
3942   else
3943     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3946 (define_insn "*truncxfsf2_mixed"
3947   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3948         (float_truncate:SF
3949          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3950    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3951   "TARGET_80387"
3953   gcc_assert (!which_alternative);
3954   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3955     return "fstp%z0\t%y0";
3956   else
3957     return "fst%z0\t%y0";
3959   [(set_attr "type" "fmov,multi,multi,multi")
3960    (set_attr "unit" "*,i387,i387,i387")
3961    (set_attr "mode" "SF")])
3963 (define_insn "truncxfsf2_i387_noop"
3964   [(set (match_operand:SF 0 "register_operand" "=f")
3965         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3966   "TARGET_80387 && flag_unsafe_math_optimizations"
3967   "* return output_387_reg_move (insn, operands);"
3968   [(set_attr "type" "fmov")
3969    (set_attr "mode" "SF")])
3971 (define_insn "*truncxfsf2_i387"
3972   [(set (match_operand:SF 0 "memory_operand" "=m")
3973         (float_truncate:SF
3974          (match_operand:XF 1 "register_operand" "f")))]
3975   "TARGET_80387"
3977   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3978     return "fstp%z0\t%y0";
3979   else
3980     return "fst%z0\t%y0";
3982   [(set_attr "type" "fmov")
3983    (set_attr "mode" "SF")])
3985 (define_split
3986   [(set (match_operand:SF 0 "register_operand" "")
3987         (float_truncate:SF
3988          (match_operand:XF 1 "register_operand" "")))
3989    (clobber (match_operand:SF 2 "memory_operand" ""))]
3990   "TARGET_80387 && reload_completed"
3991   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3992    (set (match_dup 0) (match_dup 2))]
3993   "")
3995 (define_split
3996   [(set (match_operand:SF 0 "memory_operand" "")
3997         (float_truncate:SF
3998          (match_operand:XF 1 "register_operand" "")))
3999    (clobber (match_operand:SF 2 "memory_operand" ""))]
4000   "TARGET_80387"
4001   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4002   "")
4004 ;; Conversion from XFmode to DFmode.
4006 (define_expand "truncxfdf2"
4007   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4008                    (float_truncate:DF
4009                     (match_operand:XF 1 "register_operand" "")))
4010               (clobber (match_dup 2))])]
4011   "TARGET_80387"
4013   if (flag_unsafe_math_optimizations)
4014     {
4015       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4016       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4017       if (reg != operands[0])
4018         emit_move_insn (operands[0], reg);
4019       DONE;
4020     }
4021   else
4022     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4025 (define_insn "*truncxfdf2_mixed"
4026   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4027         (float_truncate:DF
4028          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4029    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4030   "TARGET_80387"
4032   gcc_assert (!which_alternative);
4033   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4034     return "fstp%z0\t%y0";
4035   else
4036     return "fst%z0\t%y0";
4038   [(set_attr "type" "fmov,multi,multi,multi")
4039    (set_attr "unit" "*,i387,i387,i387")
4040    (set_attr "mode" "DF")])
4042 (define_insn "truncxfdf2_i387_noop"
4043   [(set (match_operand:DF 0 "register_operand" "=f")
4044         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4045   "TARGET_80387 && flag_unsafe_math_optimizations"
4046   "* return output_387_reg_move (insn, operands);"
4047   [(set_attr "type" "fmov")
4048    (set_attr "mode" "DF")])
4050 (define_insn "*truncxfdf2_i387"
4051   [(set (match_operand:DF 0 "memory_operand" "=m")
4052         (float_truncate:DF
4053           (match_operand:XF 1 "register_operand" "f")))]
4054   "TARGET_80387"
4056   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4057     return "fstp%z0\t%y0";
4058   else
4059     return "fst%z0\t%y0";
4061   [(set_attr "type" "fmov")
4062    (set_attr "mode" "DF")])
4064 (define_split
4065   [(set (match_operand:DF 0 "register_operand" "")
4066         (float_truncate:DF
4067          (match_operand:XF 1 "register_operand" "")))
4068    (clobber (match_operand:DF 2 "memory_operand" ""))]
4069   "TARGET_80387 && reload_completed"
4070   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4071    (set (match_dup 0) (match_dup 2))]
4072   "")
4074 (define_split
4075   [(set (match_operand:DF 0 "memory_operand" "")
4076         (float_truncate:DF
4077          (match_operand:XF 1 "register_operand" "")))
4078    (clobber (match_operand:DF 2 "memory_operand" ""))]
4079   "TARGET_80387"
4080   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4081   "")
4083 ;; Signed conversion to DImode.
4085 (define_expand "fix_truncxfdi2"
4086   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4087                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4088               (clobber (reg:CC FLAGS_REG))])]
4089   "TARGET_80387"
4091   if (TARGET_FISTTP)
4092    {
4093      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4094      DONE;
4095    }
4098 (define_expand "fix_trunc<mode>di2"
4099   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4100                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4101               (clobber (reg:CC FLAGS_REG))])]
4102   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4104   if (TARGET_FISTTP
4105       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4106    {
4107      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4108      DONE;
4109    }
4110   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4111    {
4112      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4113      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4114      if (out != operands[0])
4115         emit_move_insn (operands[0], out);
4116      DONE;
4117    }
4120 ;; Signed conversion to SImode.
4122 (define_expand "fix_truncxfsi2"
4123   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4124                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4125               (clobber (reg:CC FLAGS_REG))])]
4126   "TARGET_80387"
4128   if (TARGET_FISTTP)
4129    {
4130      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4131      DONE;
4132    }
4135 (define_expand "fix_trunc<mode>si2"
4136   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4137                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4138               (clobber (reg:CC FLAGS_REG))])]
4139   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4141   if (TARGET_FISTTP
4142       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4143    {
4144      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4145      DONE;
4146    }
4147   if (SSE_FLOAT_MODE_P (<MODE>mode))
4148    {
4149      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4150      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4151      if (out != operands[0])
4152         emit_move_insn (operands[0], out);
4153      DONE;
4154    }
4157 ;; Signed conversion to HImode.
4159 (define_expand "fix_trunc<mode>hi2"
4160   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4161                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4162               (clobber (reg:CC FLAGS_REG))])]
4163   "TARGET_80387
4164    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4166   if (TARGET_FISTTP)
4167    {
4168      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4169      DONE;
4170    }
4173 ;; When SSE is available, it is always faster to use it!
4174 (define_insn "fix_truncsfdi_sse"
4175   [(set (match_operand:DI 0 "register_operand" "=r,r")
4176         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4177   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4178   "cvttss2si{q}\t{%1, %0|%0, %1}"
4179   [(set_attr "type" "sseicvt")
4180    (set_attr "mode" "SF")
4181    (set_attr "athlon_decode" "double,vector")])
4183 (define_insn "fix_truncdfdi_sse"
4184   [(set (match_operand:DI 0 "register_operand" "=r,r")
4185         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4186   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4187   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4188   [(set_attr "type" "sseicvt")
4189    (set_attr "mode" "DF")
4190    (set_attr "athlon_decode" "double,vector")])
4192 (define_insn "fix_truncsfsi_sse"
4193   [(set (match_operand:SI 0 "register_operand" "=r,r")
4194         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4195   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4196   "cvttss2si\t{%1, %0|%0, %1}"
4197   [(set_attr "type" "sseicvt")
4198    (set_attr "mode" "DF")
4199    (set_attr "athlon_decode" "double,vector")])
4201 (define_insn "fix_truncdfsi_sse"
4202   [(set (match_operand:SI 0 "register_operand" "=r,r")
4203         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4204   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4205   "cvttsd2si\t{%1, %0|%0, %1}"
4206   [(set_attr "type" "sseicvt")
4207    (set_attr "mode" "DF")
4208    (set_attr "athlon_decode" "double,vector")])
4210 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4211 (define_peephole2
4212   [(set (match_operand:DF 0 "register_operand" "")
4213         (match_operand:DF 1 "memory_operand" ""))
4214    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4215         (fix:SSEMODEI24 (match_dup 0)))]
4216   "!TARGET_K8
4217    && peep2_reg_dead_p (2, operands[0])"
4218   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4219   "")
4221 (define_peephole2
4222   [(set (match_operand:SF 0 "register_operand" "")
4223         (match_operand:SF 1 "memory_operand" ""))
4224    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4225         (fix:SSEMODEI24 (match_dup 0)))]
4226   "!TARGET_K8
4227    && peep2_reg_dead_p (2, operands[0])"
4228   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4229   "")
4231 ;; Avoid vector decoded forms of the instruction.
4232 (define_peephole2
4233   [(match_scratch:DF 2 "Y")
4234    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4235         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4236   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4237   [(set (match_dup 2) (match_dup 1))
4238    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4239   "")
4241 (define_peephole2
4242   [(match_scratch:SF 2 "x")
4243    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4244         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4245   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4246   [(set (match_dup 2) (match_dup 1))
4247    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4248   "")
4250 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4251   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4252         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4253   "TARGET_FISTTP
4254    && FLOAT_MODE_P (GET_MODE (operands[1]))
4255    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4256          && (TARGET_64BIT || <MODE>mode != DImode))
4257         && TARGET_SSE_MATH)
4258    && !(reload_completed || reload_in_progress)"
4259   "#"
4260   "&& 1"
4261   [(const_int 0)]
4263   if (memory_operand (operands[0], VOIDmode))
4264     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4265   else
4266     {
4267       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4268       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4269                                                             operands[1],
4270                                                             operands[2]));
4271     }
4272   DONE;
4274   [(set_attr "type" "fisttp")
4275    (set_attr "mode" "<MODE>")])
4277 (define_insn "fix_trunc<mode>_i387_fisttp"
4278   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4279         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4280    (clobber (match_scratch:XF 2 "=&1f"))]
4281   "TARGET_FISTTP
4282    && FLOAT_MODE_P (GET_MODE (operands[1]))
4283    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4284          && (TARGET_64BIT || <MODE>mode != DImode))
4285         && TARGET_SSE_MATH)"
4286   "* return output_fix_trunc (insn, operands, 1);"
4287   [(set_attr "type" "fisttp")
4288    (set_attr "mode" "<MODE>")])
4290 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4291   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4292         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4293    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4294    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4295   "TARGET_FISTTP
4296    && FLOAT_MODE_P (GET_MODE (operands[1]))
4297    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4298         && (TARGET_64BIT || <MODE>mode != DImode))
4299         && TARGET_SSE_MATH)"
4300   "#"
4301   [(set_attr "type" "fisttp")
4302    (set_attr "mode" "<MODE>")])
4304 (define_split
4305   [(set (match_operand:X87MODEI 0 "register_operand" "")
4306         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4307    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4308    (clobber (match_scratch 3 ""))]
4309   "reload_completed"
4310   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4311               (clobber (match_dup 3))])
4312    (set (match_dup 0) (match_dup 2))]
4313   "")
4315 (define_split
4316   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4317         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4318    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4319    (clobber (match_scratch 3 ""))]
4320   "reload_completed"
4321   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4322               (clobber (match_dup 3))])]
4323   "")
4325 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4326 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4327 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4328 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4329 ;; function in i386.c.
4330 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4331   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4332         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4333    (clobber (reg:CC FLAGS_REG))]
4334   "TARGET_80387 && !TARGET_FISTTP
4335    && FLOAT_MODE_P (GET_MODE (operands[1]))
4336    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4337          && (TARGET_64BIT || <MODE>mode != DImode))
4338    && !(reload_completed || reload_in_progress)"
4339   "#"
4340   "&& 1"
4341   [(const_int 0)]
4343   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4345   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4346   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4347   if (memory_operand (operands[0], VOIDmode))
4348     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4349                                          operands[2], operands[3]));
4350   else
4351     {
4352       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4353       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4354                                                      operands[2], operands[3],
4355                                                      operands[4]));
4356     }
4357   DONE;
4359   [(set_attr "type" "fistp")
4360    (set_attr "i387_cw" "trunc")
4361    (set_attr "mode" "<MODE>")])
4363 (define_insn "fix_truncdi_i387"
4364   [(set (match_operand:DI 0 "memory_operand" "=m")
4365         (fix:DI (match_operand 1 "register_operand" "f")))
4366    (use (match_operand:HI 2 "memory_operand" "m"))
4367    (use (match_operand:HI 3 "memory_operand" "m"))
4368    (clobber (match_scratch:XF 4 "=&1f"))]
4369   "TARGET_80387 && !TARGET_FISTTP
4370    && FLOAT_MODE_P (GET_MODE (operands[1]))
4371    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4372   "* return output_fix_trunc (insn, operands, 0);"
4373   [(set_attr "type" "fistp")
4374    (set_attr "i387_cw" "trunc")
4375    (set_attr "mode" "DI")])
4377 (define_insn "fix_truncdi_i387_with_temp"
4378   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4379         (fix:DI (match_operand 1 "register_operand" "f,f")))
4380    (use (match_operand:HI 2 "memory_operand" "m,m"))
4381    (use (match_operand:HI 3 "memory_operand" "m,m"))
4382    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4383    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4384   "TARGET_80387 && !TARGET_FISTTP
4385    && FLOAT_MODE_P (GET_MODE (operands[1]))
4386    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4387   "#"
4388   [(set_attr "type" "fistp")
4389    (set_attr "i387_cw" "trunc")
4390    (set_attr "mode" "DI")])
4392 (define_split
4393   [(set (match_operand:DI 0 "register_operand" "")
4394         (fix:DI (match_operand 1 "register_operand" "")))
4395    (use (match_operand:HI 2 "memory_operand" ""))
4396    (use (match_operand:HI 3 "memory_operand" ""))
4397    (clobber (match_operand:DI 4 "memory_operand" ""))
4398    (clobber (match_scratch 5 ""))]
4399   "reload_completed"
4400   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4401               (use (match_dup 2))
4402               (use (match_dup 3))
4403               (clobber (match_dup 5))])
4404    (set (match_dup 0) (match_dup 4))]
4405   "")
4407 (define_split
4408   [(set (match_operand:DI 0 "memory_operand" "")
4409         (fix:DI (match_operand 1 "register_operand" "")))
4410    (use (match_operand:HI 2 "memory_operand" ""))
4411    (use (match_operand:HI 3 "memory_operand" ""))
4412    (clobber (match_operand:DI 4 "memory_operand" ""))
4413    (clobber (match_scratch 5 ""))]
4414   "reload_completed"
4415   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4416               (use (match_dup 2))
4417               (use (match_dup 3))
4418               (clobber (match_dup 5))])]
4419   "")
4421 (define_insn "fix_trunc<mode>_i387"
4422   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4423         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4424    (use (match_operand:HI 2 "memory_operand" "m"))
4425    (use (match_operand:HI 3 "memory_operand" "m"))]
4426   "TARGET_80387 && !TARGET_FISTTP
4427    && FLOAT_MODE_P (GET_MODE (operands[1]))
4428    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4429   "* return output_fix_trunc (insn, operands, 0);"
4430   [(set_attr "type" "fistp")
4431    (set_attr "i387_cw" "trunc")
4432    (set_attr "mode" "<MODE>")])
4434 (define_insn "fix_trunc<mode>_i387_with_temp"
4435   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4436         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4437    (use (match_operand:HI 2 "memory_operand" "m,m"))
4438    (use (match_operand:HI 3 "memory_operand" "m,m"))
4439    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4440   "TARGET_80387 && !TARGET_FISTTP
4441    && FLOAT_MODE_P (GET_MODE (operands[1]))
4442    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4443   "#"
4444   [(set_attr "type" "fistp")
4445    (set_attr "i387_cw" "trunc")
4446    (set_attr "mode" "<MODE>")])
4448 (define_split
4449   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4450         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4451    (use (match_operand:HI 2 "memory_operand" ""))
4452    (use (match_operand:HI 3 "memory_operand" ""))
4453    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4454   "reload_completed"
4455   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4456               (use (match_dup 2))
4457               (use (match_dup 3))])
4458    (set (match_dup 0) (match_dup 4))]
4459   "")
4461 (define_split
4462   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4463         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4464    (use (match_operand:HI 2 "memory_operand" ""))
4465    (use (match_operand:HI 3 "memory_operand" ""))
4466    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4467   "reload_completed"
4468   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4469               (use (match_dup 2))
4470               (use (match_dup 3))])]
4471   "")
4473 (define_insn "x86_fnstcw_1"
4474   [(set (match_operand:HI 0 "memory_operand" "=m")
4475         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4476   "TARGET_80387"
4477   "fnstcw\t%0"
4478   [(set_attr "length" "2")
4479    (set_attr "mode" "HI")
4480    (set_attr "unit" "i387")])
4482 (define_insn "x86_fldcw_1"
4483   [(set (reg:HI FPCR_REG)
4484         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4485   "TARGET_80387"
4486   "fldcw\t%0"
4487   [(set_attr "length" "2")
4488    (set_attr "mode" "HI")
4489    (set_attr "unit" "i387")
4490    (set_attr "athlon_decode" "vector")])
4492 ;; Conversion between fixed point and floating point.
4494 ;; Even though we only accept memory inputs, the backend _really_
4495 ;; wants to be able to do this between registers.
4497 (define_expand "floathisf2"
4498   [(set (match_operand:SF 0 "register_operand" "")
4499         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4500   "TARGET_80387 || TARGET_SSE_MATH"
4502   if (TARGET_SSE_MATH)
4503     {
4504       emit_insn (gen_floatsisf2 (operands[0],
4505                                  convert_to_mode (SImode, operands[1], 0)));
4506       DONE;
4507     }
4510 (define_insn "*floathisf2_i387"
4511   [(set (match_operand:SF 0 "register_operand" "=f,f")
4512         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4513   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4514   "@
4515    fild%z1\t%1
4516    #"
4517   [(set_attr "type" "fmov,multi")
4518    (set_attr "mode" "SF")
4519    (set_attr "unit" "*,i387")
4520    (set_attr "fp_int_src" "true")])
4522 (define_expand "floatsisf2"
4523   [(set (match_operand:SF 0 "register_operand" "")
4524         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4525   "TARGET_80387 || TARGET_SSE_MATH"
4526   "")
4528 (define_insn "*floatsisf2_mixed"
4529   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4530         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4531   "TARGET_MIX_SSE_I387"
4532   "@
4533    fild%z1\t%1
4534    #
4535    cvtsi2ss\t{%1, %0|%0, %1}
4536    cvtsi2ss\t{%1, %0|%0, %1}"
4537   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4538    (set_attr "mode" "SF")
4539    (set_attr "unit" "*,i387,*,*")
4540    (set_attr "athlon_decode" "*,*,vector,double")
4541    (set_attr "fp_int_src" "true")])
4543 (define_insn "*floatsisf2_sse"
4544   [(set (match_operand:SF 0 "register_operand" "=x,x")
4545         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4546   "TARGET_SSE_MATH"
4547   "cvtsi2ss\t{%1, %0|%0, %1}"
4548   [(set_attr "type" "sseicvt")
4549    (set_attr "mode" "SF")
4550    (set_attr "athlon_decode" "vector,double")
4551    (set_attr "fp_int_src" "true")])
4553 (define_insn "*floatsisf2_i387"
4554   [(set (match_operand:SF 0 "register_operand" "=f,f")
4555         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4556   "TARGET_80387"
4557   "@
4558    fild%z1\t%1
4559    #"
4560   [(set_attr "type" "fmov,multi")
4561    (set_attr "mode" "SF")
4562    (set_attr "unit" "*,i387")
4563    (set_attr "fp_int_src" "true")])
4565 (define_expand "floatdisf2"
4566   [(set (match_operand:SF 0 "register_operand" "")
4567         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4568   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4569   "")
4571 (define_insn "*floatdisf2_mixed"
4572   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4573         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4574   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4575   "@
4576    fild%z1\t%1
4577    #
4578    cvtsi2ss{q}\t{%1, %0|%0, %1}
4579    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4580   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4581    (set_attr "mode" "SF")
4582    (set_attr "unit" "*,i387,*,*")
4583    (set_attr "athlon_decode" "*,*,vector,double")
4584    (set_attr "fp_int_src" "true")])
4586 (define_insn "*floatdisf2_sse"
4587   [(set (match_operand:SF 0 "register_operand" "=x,x")
4588         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4589   "TARGET_64BIT && TARGET_SSE_MATH"
4590   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4591   [(set_attr "type" "sseicvt")
4592    (set_attr "mode" "SF")
4593    (set_attr "athlon_decode" "vector,double")
4594    (set_attr "fp_int_src" "true")])
4596 (define_insn "*floatdisf2_i387"
4597   [(set (match_operand:SF 0 "register_operand" "=f,f")
4598         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4599   "TARGET_80387"
4600   "@
4601    fild%z1\t%1
4602    #"
4603   [(set_attr "type" "fmov,multi")
4604    (set_attr "mode" "SF")
4605    (set_attr "unit" "*,i387")
4606    (set_attr "fp_int_src" "true")])
4608 (define_expand "floathidf2"
4609   [(set (match_operand:DF 0 "register_operand" "")
4610         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4611   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4613   if (TARGET_SSE2 && TARGET_SSE_MATH)
4614     {
4615       emit_insn (gen_floatsidf2 (operands[0],
4616                                  convert_to_mode (SImode, operands[1], 0)));
4617       DONE;
4618     }
4621 (define_insn "*floathidf2_i387"
4622   [(set (match_operand:DF 0 "register_operand" "=f,f")
4623         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4624   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4625   "@
4626    fild%z1\t%1
4627    #"
4628   [(set_attr "type" "fmov,multi")
4629    (set_attr "mode" "DF")
4630    (set_attr "unit" "*,i387")
4631    (set_attr "fp_int_src" "true")])
4633 (define_expand "floatsidf2"
4634   [(set (match_operand:DF 0 "register_operand" "")
4635         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4636   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4637   "")
4639 (define_insn "*floatsidf2_mixed"
4640   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4641         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4642   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4643   "@
4644    fild%z1\t%1
4645    #
4646    cvtsi2sd\t{%1, %0|%0, %1}
4647    cvtsi2sd\t{%1, %0|%0, %1}"
4648   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4649    (set_attr "mode" "DF")
4650    (set_attr "unit" "*,i387,*,*")
4651    (set_attr "athlon_decode" "*,*,double,direct")
4652    (set_attr "fp_int_src" "true")])
4654 (define_insn "*floatsidf2_sse"
4655   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4656         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4657   "TARGET_SSE2 && TARGET_SSE_MATH"
4658   "cvtsi2sd\t{%1, %0|%0, %1}"
4659   [(set_attr "type" "sseicvt")
4660    (set_attr "mode" "DF")
4661    (set_attr "athlon_decode" "double,direct")
4662    (set_attr "fp_int_src" "true")])
4664 (define_insn "*floatsidf2_i387"
4665   [(set (match_operand:DF 0 "register_operand" "=f,f")
4666         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4667   "TARGET_80387"
4668   "@
4669    fild%z1\t%1
4670    #"
4671   [(set_attr "type" "fmov,multi")
4672    (set_attr "mode" "DF")
4673    (set_attr "unit" "*,i387")
4674    (set_attr "fp_int_src" "true")])
4676 (define_expand "floatdidf2"
4677   [(set (match_operand:DF 0 "register_operand" "")
4678         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4679   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4680   "")
4682 (define_insn "*floatdidf2_mixed"
4683   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4684         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4685   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4686   "@
4687    fild%z1\t%1
4688    #
4689    cvtsi2sd{q}\t{%1, %0|%0, %1}
4690    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4691   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4692    (set_attr "mode" "DF")
4693    (set_attr "unit" "*,i387,*,*")
4694    (set_attr "athlon_decode" "*,*,double,direct")
4695    (set_attr "fp_int_src" "true")])
4697 (define_insn "*floatdidf2_sse"
4698   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4699         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4700   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4701   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4702   [(set_attr "type" "sseicvt")
4703    (set_attr "mode" "DF")
4704    (set_attr "athlon_decode" "double,direct")
4705    (set_attr "fp_int_src" "true")])
4707 (define_insn "*floatdidf2_i387"
4708   [(set (match_operand:DF 0 "register_operand" "=f,f")
4709         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4710   "TARGET_80387"
4711   "@
4712    fild%z1\t%1
4713    #"
4714   [(set_attr "type" "fmov,multi")
4715    (set_attr "mode" "DF")
4716    (set_attr "unit" "*,i387")
4717    (set_attr "fp_int_src" "true")])
4719 (define_insn "floathixf2"
4720   [(set (match_operand:XF 0 "register_operand" "=f,f")
4721         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4722   "TARGET_80387"
4723   "@
4724    fild%z1\t%1
4725    #"
4726   [(set_attr "type" "fmov,multi")
4727    (set_attr "mode" "XF")
4728    (set_attr "unit" "*,i387")
4729    (set_attr "fp_int_src" "true")])
4731 (define_insn "floatsixf2"
4732   [(set (match_operand:XF 0 "register_operand" "=f,f")
4733         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4734   "TARGET_80387"
4735   "@
4736    fild%z1\t%1
4737    #"
4738   [(set_attr "type" "fmov,multi")
4739    (set_attr "mode" "XF")
4740    (set_attr "unit" "*,i387")
4741    (set_attr "fp_int_src" "true")])
4743 (define_insn "floatdixf2"
4744   [(set (match_operand:XF 0 "register_operand" "=f,f")
4745         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4746   "TARGET_80387"
4747   "@
4748    fild%z1\t%1
4749    #"
4750   [(set_attr "type" "fmov,multi")
4751    (set_attr "mode" "XF")
4752    (set_attr "unit" "*,i387")
4753    (set_attr "fp_int_src" "true")])
4755 ;; %%% Kill these when reload knows how to do it.
4756 (define_split
4757   [(set (match_operand 0 "fp_register_operand" "")
4758         (float (match_operand 1 "register_operand" "")))]
4759   "reload_completed
4760    && TARGET_80387
4761    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4762   [(const_int 0)]
4764   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4765   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4766   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4767   ix86_free_from_memory (GET_MODE (operands[1]));
4768   DONE;
4771 (define_expand "floatunssisf2"
4772   [(use (match_operand:SF 0 "register_operand" ""))
4773    (use (match_operand:SI 1 "register_operand" ""))]
4774   "!TARGET_64BIT && TARGET_SSE_MATH"
4775   "x86_emit_floatuns (operands); DONE;")
4777 (define_expand "floatunsdisf2"
4778   [(use (match_operand:SF 0 "register_operand" ""))
4779    (use (match_operand:DI 1 "register_operand" ""))]
4780   "TARGET_64BIT && TARGET_SSE_MATH"
4781   "x86_emit_floatuns (operands); DONE;")
4783 (define_expand "floatunsdidf2"
4784   [(use (match_operand:DF 0 "register_operand" ""))
4785    (use (match_operand:DI 1 "register_operand" ""))]
4786   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4787   "x86_emit_floatuns (operands); DONE;")
4789 ;; SSE extract/set expanders
4792 ;; Add instructions
4794 ;; %%% splits for addditi3
4796 (define_expand "addti3"
4797   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4798         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4799                  (match_operand:TI 2 "x86_64_general_operand" "")))
4800    (clobber (reg:CC FLAGS_REG))]
4801   "TARGET_64BIT"
4802   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4804 (define_insn "*addti3_1"
4805   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4806         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4807                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4808    (clobber (reg:CC FLAGS_REG))]
4809   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4810   "#")
4812 (define_split
4813   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4814         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4815                  (match_operand:TI 2 "general_operand" "")))
4816    (clobber (reg:CC FLAGS_REG))]
4817   "TARGET_64BIT && reload_completed"
4818   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4819                                           UNSPEC_ADD_CARRY))
4820               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4821    (parallel [(set (match_dup 3)
4822                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4823                                      (match_dup 4))
4824                             (match_dup 5)))
4825               (clobber (reg:CC FLAGS_REG))])]
4826   "split_ti (operands+0, 1, operands+0, operands+3);
4827    split_ti (operands+1, 1, operands+1, operands+4);
4828    split_ti (operands+2, 1, operands+2, operands+5);")
4830 ;; %%% splits for addsidi3
4831 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4832 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4833 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4835 (define_expand "adddi3"
4836   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4837         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4838                  (match_operand:DI 2 "x86_64_general_operand" "")))
4839    (clobber (reg:CC FLAGS_REG))]
4840   ""
4841   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4843 (define_insn "*adddi3_1"
4844   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4845         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4846                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4847    (clobber (reg:CC FLAGS_REG))]
4848   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4849   "#")
4851 (define_split
4852   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4853         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4854                  (match_operand:DI 2 "general_operand" "")))
4855    (clobber (reg:CC FLAGS_REG))]
4856   "!TARGET_64BIT && reload_completed"
4857   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4858                                           UNSPEC_ADD_CARRY))
4859               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4860    (parallel [(set (match_dup 3)
4861                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4862                                      (match_dup 4))
4863                             (match_dup 5)))
4864               (clobber (reg:CC FLAGS_REG))])]
4865   "split_di (operands+0, 1, operands+0, operands+3);
4866    split_di (operands+1, 1, operands+1, operands+4);
4867    split_di (operands+2, 1, operands+2, operands+5);")
4869 (define_insn "adddi3_carry_rex64"
4870   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4871           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4872                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4873                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4874    (clobber (reg:CC FLAGS_REG))]
4875   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4876   "adc{q}\t{%2, %0|%0, %2}"
4877   [(set_attr "type" "alu")
4878    (set_attr "pent_pair" "pu")
4879    (set_attr "mode" "DI")])
4881 (define_insn "*adddi3_cc_rex64"
4882   [(set (reg:CC FLAGS_REG)
4883         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4884                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4885                    UNSPEC_ADD_CARRY))
4886    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4887         (plus:DI (match_dup 1) (match_dup 2)))]
4888   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4889   "add{q}\t{%2, %0|%0, %2}"
4890   [(set_attr "type" "alu")
4891    (set_attr "mode" "DI")])
4893 (define_insn "addqi3_carry"
4894   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4895           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4896                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4897                    (match_operand:QI 2 "general_operand" "qi,qm")))
4898    (clobber (reg:CC FLAGS_REG))]
4899   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4900   "adc{b}\t{%2, %0|%0, %2}"
4901   [(set_attr "type" "alu")
4902    (set_attr "pent_pair" "pu")
4903    (set_attr "mode" "QI")])
4905 (define_insn "addhi3_carry"
4906   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4907           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4908                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4909                    (match_operand:HI 2 "general_operand" "ri,rm")))
4910    (clobber (reg:CC FLAGS_REG))]
4911   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4912   "adc{w}\t{%2, %0|%0, %2}"
4913   [(set_attr "type" "alu")
4914    (set_attr "pent_pair" "pu")
4915    (set_attr "mode" "HI")])
4917 (define_insn "addsi3_carry"
4918   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4919           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4920                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4921                    (match_operand:SI 2 "general_operand" "ri,rm")))
4922    (clobber (reg:CC FLAGS_REG))]
4923   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4924   "adc{l}\t{%2, %0|%0, %2}"
4925   [(set_attr "type" "alu")
4926    (set_attr "pent_pair" "pu")
4927    (set_attr "mode" "SI")])
4929 (define_insn "*addsi3_carry_zext"
4930   [(set (match_operand:DI 0 "register_operand" "=r")
4931           (zero_extend:DI
4932             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4933                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4934                      (match_operand:SI 2 "general_operand" "rim"))))
4935    (clobber (reg:CC FLAGS_REG))]
4936   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4937   "adc{l}\t{%2, %k0|%k0, %2}"
4938   [(set_attr "type" "alu")
4939    (set_attr "pent_pair" "pu")
4940    (set_attr "mode" "SI")])
4942 (define_insn "*addsi3_cc"
4943   [(set (reg:CC FLAGS_REG)
4944         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4945                     (match_operand:SI 2 "general_operand" "ri,rm")]
4946                    UNSPEC_ADD_CARRY))
4947    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4948         (plus:SI (match_dup 1) (match_dup 2)))]
4949   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4950   "add{l}\t{%2, %0|%0, %2}"
4951   [(set_attr "type" "alu")
4952    (set_attr "mode" "SI")])
4954 (define_insn "addqi3_cc"
4955   [(set (reg:CC FLAGS_REG)
4956         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4957                     (match_operand:QI 2 "general_operand" "qi,qm")]
4958                    UNSPEC_ADD_CARRY))
4959    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4960         (plus:QI (match_dup 1) (match_dup 2)))]
4961   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4962   "add{b}\t{%2, %0|%0, %2}"
4963   [(set_attr "type" "alu")
4964    (set_attr "mode" "QI")])
4966 (define_expand "addsi3"
4967   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4968                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4969                             (match_operand:SI 2 "general_operand" "")))
4970               (clobber (reg:CC FLAGS_REG))])]
4971   ""
4972   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4974 (define_insn "*lea_1"
4975   [(set (match_operand:SI 0 "register_operand" "=r")
4976         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4977   "!TARGET_64BIT"
4978   "lea{l}\t{%a1, %0|%0, %a1}"
4979   [(set_attr "type" "lea")
4980    (set_attr "mode" "SI")])
4982 (define_insn "*lea_1_rex64"
4983   [(set (match_operand:SI 0 "register_operand" "=r")
4984         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4985   "TARGET_64BIT"
4986   "lea{l}\t{%a1, %0|%0, %a1}"
4987   [(set_attr "type" "lea")
4988    (set_attr "mode" "SI")])
4990 (define_insn "*lea_1_zext"
4991   [(set (match_operand:DI 0 "register_operand" "=r")
4992         (zero_extend:DI
4993          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4994   "TARGET_64BIT"
4995   "lea{l}\t{%a1, %k0|%k0, %a1}"
4996   [(set_attr "type" "lea")
4997    (set_attr "mode" "SI")])
4999 (define_insn "*lea_2_rex64"
5000   [(set (match_operand:DI 0 "register_operand" "=r")
5001         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5002   "TARGET_64BIT"
5003   "lea{q}\t{%a1, %0|%0, %a1}"
5004   [(set_attr "type" "lea")
5005    (set_attr "mode" "DI")])
5007 ;; The lea patterns for non-Pmodes needs to be matched by several
5008 ;; insns converted to real lea by splitters.
5010 (define_insn_and_split "*lea_general_1"
5011   [(set (match_operand 0 "register_operand" "=r")
5012         (plus (plus (match_operand 1 "index_register_operand" "l")
5013                     (match_operand 2 "register_operand" "r"))
5014               (match_operand 3 "immediate_operand" "i")))]
5015   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5016     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5017    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5018    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5019    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5020    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5021        || GET_MODE (operands[3]) == VOIDmode)"
5022   "#"
5023   "&& reload_completed"
5024   [(const_int 0)]
5026   rtx pat;
5027   operands[0] = gen_lowpart (SImode, operands[0]);
5028   operands[1] = gen_lowpart (Pmode, operands[1]);
5029   operands[2] = gen_lowpart (Pmode, operands[2]);
5030   operands[3] = gen_lowpart (Pmode, operands[3]);
5031   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5032                       operands[3]);
5033   if (Pmode != SImode)
5034     pat = gen_rtx_SUBREG (SImode, pat, 0);
5035   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5036   DONE;
5038   [(set_attr "type" "lea")
5039    (set_attr "mode" "SI")])
5041 (define_insn_and_split "*lea_general_1_zext"
5042   [(set (match_operand:DI 0 "register_operand" "=r")
5043         (zero_extend:DI
5044           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5045                             (match_operand:SI 2 "register_operand" "r"))
5046                    (match_operand:SI 3 "immediate_operand" "i"))))]
5047   "TARGET_64BIT"
5048   "#"
5049   "&& reload_completed"
5050   [(set (match_dup 0)
5051         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5052                                                      (match_dup 2))
5053                                             (match_dup 3)) 0)))]
5055   operands[1] = gen_lowpart (Pmode, operands[1]);
5056   operands[2] = gen_lowpart (Pmode, operands[2]);
5057   operands[3] = gen_lowpart (Pmode, operands[3]);
5059   [(set_attr "type" "lea")
5060    (set_attr "mode" "SI")])
5062 (define_insn_and_split "*lea_general_2"
5063   [(set (match_operand 0 "register_operand" "=r")
5064         (plus (mult (match_operand 1 "index_register_operand" "l")
5065                     (match_operand 2 "const248_operand" "i"))
5066               (match_operand 3 "nonmemory_operand" "ri")))]
5067   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5068     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5069    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5070    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5071    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5072        || GET_MODE (operands[3]) == VOIDmode)"
5073   "#"
5074   "&& reload_completed"
5075   [(const_int 0)]
5077   rtx pat;
5078   operands[0] = gen_lowpart (SImode, operands[0]);
5079   operands[1] = gen_lowpart (Pmode, operands[1]);
5080   operands[3] = gen_lowpart (Pmode, operands[3]);
5081   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5082                       operands[3]);
5083   if (Pmode != SImode)
5084     pat = gen_rtx_SUBREG (SImode, pat, 0);
5085   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5086   DONE;
5088   [(set_attr "type" "lea")
5089    (set_attr "mode" "SI")])
5091 (define_insn_and_split "*lea_general_2_zext"
5092   [(set (match_operand:DI 0 "register_operand" "=r")
5093         (zero_extend:DI
5094           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5095                             (match_operand:SI 2 "const248_operand" "n"))
5096                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5097   "TARGET_64BIT"
5098   "#"
5099   "&& reload_completed"
5100   [(set (match_dup 0)
5101         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5102                                                      (match_dup 2))
5103                                             (match_dup 3)) 0)))]
5105   operands[1] = gen_lowpart (Pmode, operands[1]);
5106   operands[3] = gen_lowpart (Pmode, operands[3]);
5108   [(set_attr "type" "lea")
5109    (set_attr "mode" "SI")])
5111 (define_insn_and_split "*lea_general_3"
5112   [(set (match_operand 0 "register_operand" "=r")
5113         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5114                           (match_operand 2 "const248_operand" "i"))
5115                     (match_operand 3 "register_operand" "r"))
5116               (match_operand 4 "immediate_operand" "i")))]
5117   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5118     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5119    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5120    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5121    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5122   "#"
5123   "&& reload_completed"
5124   [(const_int 0)]
5126   rtx pat;
5127   operands[0] = gen_lowpart (SImode, operands[0]);
5128   operands[1] = gen_lowpart (Pmode, operands[1]);
5129   operands[3] = gen_lowpart (Pmode, operands[3]);
5130   operands[4] = gen_lowpart (Pmode, operands[4]);
5131   pat = gen_rtx_PLUS (Pmode,
5132                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5133                                                          operands[2]),
5134                                     operands[3]),
5135                       operands[4]);
5136   if (Pmode != SImode)
5137     pat = gen_rtx_SUBREG (SImode, pat, 0);
5138   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5139   DONE;
5141   [(set_attr "type" "lea")
5142    (set_attr "mode" "SI")])
5144 (define_insn_and_split "*lea_general_3_zext"
5145   [(set (match_operand:DI 0 "register_operand" "=r")
5146         (zero_extend:DI
5147           (plus:SI (plus:SI (mult:SI
5148                               (match_operand:SI 1 "index_register_operand" "l")
5149                               (match_operand:SI 2 "const248_operand" "n"))
5150                             (match_operand:SI 3 "register_operand" "r"))
5151                    (match_operand:SI 4 "immediate_operand" "i"))))]
5152   "TARGET_64BIT"
5153   "#"
5154   "&& reload_completed"
5155   [(set (match_dup 0)
5156         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5157                                                               (match_dup 2))
5158                                                      (match_dup 3))
5159                                             (match_dup 4)) 0)))]
5161   operands[1] = gen_lowpart (Pmode, operands[1]);
5162   operands[3] = gen_lowpart (Pmode, operands[3]);
5163   operands[4] = gen_lowpart (Pmode, operands[4]);
5165   [(set_attr "type" "lea")
5166    (set_attr "mode" "SI")])
5168 (define_insn "*adddi_1_rex64"
5169   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5170         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5171                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5172    (clobber (reg:CC FLAGS_REG))]
5173   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5175   switch (get_attr_type (insn))
5176     {
5177     case TYPE_LEA:
5178       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5179       return "lea{q}\t{%a2, %0|%0, %a2}";
5181     case TYPE_INCDEC:
5182       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5183       if (operands[2] == const1_rtx)
5184         return "inc{q}\t%0";
5185       else
5186         {
5187           gcc_assert (operands[2] == constm1_rtx);
5188           return "dec{q}\t%0";
5189         }
5191     default:
5192       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5194       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5195          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5196       if (CONST_INT_P (operands[2])
5197           /* Avoid overflows.  */
5198           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5199           && (INTVAL (operands[2]) == 128
5200               || (INTVAL (operands[2]) < 0
5201                   && INTVAL (operands[2]) != -128)))
5202         {
5203           operands[2] = GEN_INT (-INTVAL (operands[2]));
5204           return "sub{q}\t{%2, %0|%0, %2}";
5205         }
5206       return "add{q}\t{%2, %0|%0, %2}";
5207     }
5209   [(set (attr "type")
5210      (cond [(eq_attr "alternative" "2")
5211               (const_string "lea")
5212             ; Current assemblers are broken and do not allow @GOTOFF in
5213             ; ought but a memory context.
5214             (match_operand:DI 2 "pic_symbolic_operand" "")
5215               (const_string "lea")
5216             (match_operand:DI 2 "incdec_operand" "")
5217               (const_string "incdec")
5218            ]
5219            (const_string "alu")))
5220    (set_attr "mode" "DI")])
5222 ;; Convert lea to the lea pattern to avoid flags dependency.
5223 (define_split
5224   [(set (match_operand:DI 0 "register_operand" "")
5225         (plus:DI (match_operand:DI 1 "register_operand" "")
5226                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5227    (clobber (reg:CC FLAGS_REG))]
5228   "TARGET_64BIT && reload_completed
5229    && true_regnum (operands[0]) != true_regnum (operands[1])"
5230   [(set (match_dup 0)
5231         (plus:DI (match_dup 1)
5232                  (match_dup 2)))]
5233   "")
5235 (define_insn "*adddi_2_rex64"
5236   [(set (reg FLAGS_REG)
5237         (compare
5238           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5239                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5240           (const_int 0)))
5241    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5242         (plus:DI (match_dup 1) (match_dup 2)))]
5243   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5244    && ix86_binary_operator_ok (PLUS, DImode, operands)
5245    /* Current assemblers are broken and do not allow @GOTOFF in
5246       ought but a memory context.  */
5247    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5249   switch (get_attr_type (insn))
5250     {
5251     case TYPE_INCDEC:
5252       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5253       if (operands[2] == const1_rtx)
5254         return "inc{q}\t%0";
5255       else
5256         {
5257           gcc_assert (operands[2] == constm1_rtx);
5258           return "dec{q}\t%0";
5259         }
5261     default:
5262       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5263       /* ???? We ought to handle there the 32bit case too
5264          - do we need new constraint?  */
5265       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5266          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5267       if (CONST_INT_P (operands[2])
5268           /* Avoid overflows.  */
5269           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5270           && (INTVAL (operands[2]) == 128
5271               || (INTVAL (operands[2]) < 0
5272                   && INTVAL (operands[2]) != -128)))
5273         {
5274           operands[2] = GEN_INT (-INTVAL (operands[2]));
5275           return "sub{q}\t{%2, %0|%0, %2}";
5276         }
5277       return "add{q}\t{%2, %0|%0, %2}";
5278     }
5280   [(set (attr "type")
5281      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5282         (const_string "incdec")
5283         (const_string "alu")))
5284    (set_attr "mode" "DI")])
5286 (define_insn "*adddi_3_rex64"
5287   [(set (reg FLAGS_REG)
5288         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5289                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5290    (clobber (match_scratch:DI 0 "=r"))]
5291   "TARGET_64BIT
5292    && ix86_match_ccmode (insn, CCZmode)
5293    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5294    /* Current assemblers are broken and do not allow @GOTOFF in
5295       ought but a memory context.  */
5296    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5298   switch (get_attr_type (insn))
5299     {
5300     case TYPE_INCDEC:
5301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5302       if (operands[2] == const1_rtx)
5303         return "inc{q}\t%0";
5304       else
5305         {
5306           gcc_assert (operands[2] == constm1_rtx);
5307           return "dec{q}\t%0";
5308         }
5310     default:
5311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5312       /* ???? We ought to handle there the 32bit case too
5313          - do we need new constraint?  */
5314       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5315          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5316       if (CONST_INT_P (operands[2])
5317           /* Avoid overflows.  */
5318           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5319           && (INTVAL (operands[2]) == 128
5320               || (INTVAL (operands[2]) < 0
5321                   && INTVAL (operands[2]) != -128)))
5322         {
5323           operands[2] = GEN_INT (-INTVAL (operands[2]));
5324           return "sub{q}\t{%2, %0|%0, %2}";
5325         }
5326       return "add{q}\t{%2, %0|%0, %2}";
5327     }
5329   [(set (attr "type")
5330      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5331         (const_string "incdec")
5332         (const_string "alu")))
5333    (set_attr "mode" "DI")])
5335 ; For comparisons against 1, -1 and 128, we may generate better code
5336 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5337 ; is matched then.  We can't accept general immediate, because for
5338 ; case of overflows,  the result is messed up.
5339 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5340 ; when negated.
5341 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5342 ; only for comparisons not depending on it.
5343 (define_insn "*adddi_4_rex64"
5344   [(set (reg FLAGS_REG)
5345         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5346                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5347    (clobber (match_scratch:DI 0 "=rm"))]
5348   "TARGET_64BIT
5349    &&  ix86_match_ccmode (insn, CCGCmode)"
5351   switch (get_attr_type (insn))
5352     {
5353     case TYPE_INCDEC:
5354       if (operands[2] == constm1_rtx)
5355         return "inc{q}\t%0";
5356       else
5357         {
5358           gcc_assert (operands[2] == const1_rtx);
5359           return "dec{q}\t%0";
5360         }
5362     default:
5363       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5364       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5365          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5366       if ((INTVAL (operands[2]) == -128
5367            || (INTVAL (operands[2]) > 0
5368                && INTVAL (operands[2]) != 128))
5369           /* Avoid overflows.  */
5370           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5371         return "sub{q}\t{%2, %0|%0, %2}";
5372       operands[2] = GEN_INT (-INTVAL (operands[2]));
5373       return "add{q}\t{%2, %0|%0, %2}";
5374     }
5376   [(set (attr "type")
5377      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378         (const_string "incdec")
5379         (const_string "alu")))
5380    (set_attr "mode" "DI")])
5382 (define_insn "*adddi_5_rex64"
5383   [(set (reg FLAGS_REG)
5384         (compare
5385           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5386                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5387           (const_int 0)))
5388    (clobber (match_scratch:DI 0 "=r"))]
5389   "TARGET_64BIT
5390    && ix86_match_ccmode (insn, CCGOCmode)
5391    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5392    /* Current assemblers are broken and do not allow @GOTOFF in
5393       ought but a memory context.  */
5394    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5396   switch (get_attr_type (insn))
5397     {
5398     case TYPE_INCDEC:
5399       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5400       if (operands[2] == const1_rtx)
5401         return "inc{q}\t%0";
5402       else
5403         {
5404           gcc_assert (operands[2] == constm1_rtx);
5405           return "dec{q}\t%0";
5406         }
5408     default:
5409       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5410       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5411          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5412       if (CONST_INT_P (operands[2])
5413           /* Avoid overflows.  */
5414           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5415           && (INTVAL (operands[2]) == 128
5416               || (INTVAL (operands[2]) < 0
5417                   && INTVAL (operands[2]) != -128)))
5418         {
5419           operands[2] = GEN_INT (-INTVAL (operands[2]));
5420           return "sub{q}\t{%2, %0|%0, %2}";
5421         }
5422       return "add{q}\t{%2, %0|%0, %2}";
5423     }
5425   [(set (attr "type")
5426      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5427         (const_string "incdec")
5428         (const_string "alu")))
5429    (set_attr "mode" "DI")])
5432 (define_insn "*addsi_1"
5433   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5434         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5435                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5436    (clobber (reg:CC FLAGS_REG))]
5437   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5439   switch (get_attr_type (insn))
5440     {
5441     case TYPE_LEA:
5442       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5443       return "lea{l}\t{%a2, %0|%0, %a2}";
5445     case TYPE_INCDEC:
5446       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5447       if (operands[2] == const1_rtx)
5448         return "inc{l}\t%0";
5449       else
5450         {
5451           gcc_assert (operands[2] == constm1_rtx);
5452           return "dec{l}\t%0";
5453         }
5455     default:
5456       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5458       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5459          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5460       if (CONST_INT_P (operands[2])
5461           && (INTVAL (operands[2]) == 128
5462               || (INTVAL (operands[2]) < 0
5463                   && INTVAL (operands[2]) != -128)))
5464         {
5465           operands[2] = GEN_INT (-INTVAL (operands[2]));
5466           return "sub{l}\t{%2, %0|%0, %2}";
5467         }
5468       return "add{l}\t{%2, %0|%0, %2}";
5469     }
5471   [(set (attr "type")
5472      (cond [(eq_attr "alternative" "2")
5473               (const_string "lea")
5474             ; Current assemblers are broken and do not allow @GOTOFF in
5475             ; ought but a memory context.
5476             (match_operand:SI 2 "pic_symbolic_operand" "")
5477               (const_string "lea")
5478             (match_operand:SI 2 "incdec_operand" "")
5479               (const_string "incdec")
5480            ]
5481            (const_string "alu")))
5482    (set_attr "mode" "SI")])
5484 ;; Convert lea to the lea pattern to avoid flags dependency.
5485 (define_split
5486   [(set (match_operand 0 "register_operand" "")
5487         (plus (match_operand 1 "register_operand" "")
5488               (match_operand 2 "nonmemory_operand" "")))
5489    (clobber (reg:CC FLAGS_REG))]
5490   "reload_completed
5491    && true_regnum (operands[0]) != true_regnum (operands[1])"
5492   [(const_int 0)]
5494   rtx pat;
5495   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5496      may confuse gen_lowpart.  */
5497   if (GET_MODE (operands[0]) != Pmode)
5498     {
5499       operands[1] = gen_lowpart (Pmode, operands[1]);
5500       operands[2] = gen_lowpart (Pmode, operands[2]);
5501     }
5502   operands[0] = gen_lowpart (SImode, operands[0]);
5503   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5504   if (Pmode != SImode)
5505     pat = gen_rtx_SUBREG (SImode, pat, 0);
5506   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5507   DONE;
5510 ;; It may seem that nonimmediate operand is proper one for operand 1.
5511 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5512 ;; we take care in ix86_binary_operator_ok to not allow two memory
5513 ;; operands so proper swapping will be done in reload.  This allow
5514 ;; patterns constructed from addsi_1 to match.
5515 (define_insn "addsi_1_zext"
5516   [(set (match_operand:DI 0 "register_operand" "=r,r")
5517         (zero_extend:DI
5518           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5519                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5520    (clobber (reg:CC FLAGS_REG))]
5521   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5523   switch (get_attr_type (insn))
5524     {
5525     case TYPE_LEA:
5526       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5527       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5529     case TYPE_INCDEC:
5530       if (operands[2] == const1_rtx)
5531         return "inc{l}\t%k0";
5532       else
5533         {
5534           gcc_assert (operands[2] == constm1_rtx);
5535           return "dec{l}\t%k0";
5536         }
5538     default:
5539       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5540          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5541       if (CONST_INT_P (operands[2])
5542           && (INTVAL (operands[2]) == 128
5543               || (INTVAL (operands[2]) < 0
5544                   && INTVAL (operands[2]) != -128)))
5545         {
5546           operands[2] = GEN_INT (-INTVAL (operands[2]));
5547           return "sub{l}\t{%2, %k0|%k0, %2}";
5548         }
5549       return "add{l}\t{%2, %k0|%k0, %2}";
5550     }
5552   [(set (attr "type")
5553      (cond [(eq_attr "alternative" "1")
5554               (const_string "lea")
5555             ; Current assemblers are broken and do not allow @GOTOFF in
5556             ; ought but a memory context.
5557             (match_operand:SI 2 "pic_symbolic_operand" "")
5558               (const_string "lea")
5559             (match_operand:SI 2 "incdec_operand" "")
5560               (const_string "incdec")
5561            ]
5562            (const_string "alu")))
5563    (set_attr "mode" "SI")])
5565 ;; Convert lea to the lea pattern to avoid flags dependency.
5566 (define_split
5567   [(set (match_operand:DI 0 "register_operand" "")
5568         (zero_extend:DI
5569           (plus:SI (match_operand:SI 1 "register_operand" "")
5570                    (match_operand:SI 2 "nonmemory_operand" ""))))
5571    (clobber (reg:CC FLAGS_REG))]
5572   "TARGET_64BIT && reload_completed
5573    && true_regnum (operands[0]) != true_regnum (operands[1])"
5574   [(set (match_dup 0)
5575         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5577   operands[1] = gen_lowpart (Pmode, operands[1]);
5578   operands[2] = gen_lowpart (Pmode, operands[2]);
5581 (define_insn "*addsi_2"
5582   [(set (reg FLAGS_REG)
5583         (compare
5584           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5585                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5586           (const_int 0)))
5587    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5588         (plus:SI (match_dup 1) (match_dup 2)))]
5589   "ix86_match_ccmode (insn, CCGOCmode)
5590    && ix86_binary_operator_ok (PLUS, SImode, operands)
5591    /* Current assemblers are broken and do not allow @GOTOFF in
5592       ought but a memory context.  */
5593    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5595   switch (get_attr_type (insn))
5596     {
5597     case TYPE_INCDEC:
5598       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599       if (operands[2] == const1_rtx)
5600         return "inc{l}\t%0";
5601       else
5602         {
5603           gcc_assert (operands[2] == constm1_rtx);
5604           return "dec{l}\t%0";
5605         }
5607     default:
5608       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5610          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5611       if (CONST_INT_P (operands[2])
5612           && (INTVAL (operands[2]) == 128
5613               || (INTVAL (operands[2]) < 0
5614                   && INTVAL (operands[2]) != -128)))
5615         {
5616           operands[2] = GEN_INT (-INTVAL (operands[2]));
5617           return "sub{l}\t{%2, %0|%0, %2}";
5618         }
5619       return "add{l}\t{%2, %0|%0, %2}";
5620     }
5622   [(set (attr "type")
5623      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5624         (const_string "incdec")
5625         (const_string "alu")))
5626    (set_attr "mode" "SI")])
5628 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5629 (define_insn "*addsi_2_zext"
5630   [(set (reg FLAGS_REG)
5631         (compare
5632           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5633                    (match_operand:SI 2 "general_operand" "rmni"))
5634           (const_int 0)))
5635    (set (match_operand:DI 0 "register_operand" "=r")
5636         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5637   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5638    && ix86_binary_operator_ok (PLUS, SImode, operands)
5639    /* Current assemblers are broken and do not allow @GOTOFF in
5640       ought but a memory context.  */
5641    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5643   switch (get_attr_type (insn))
5644     {
5645     case TYPE_INCDEC:
5646       if (operands[2] == const1_rtx)
5647         return "inc{l}\t%k0";
5648       else
5649         {
5650           gcc_assert (operands[2] == constm1_rtx);
5651           return "dec{l}\t%k0";
5652         }
5654     default:
5655       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5657       if (CONST_INT_P (operands[2])
5658           && (INTVAL (operands[2]) == 128
5659               || (INTVAL (operands[2]) < 0
5660                   && INTVAL (operands[2]) != -128)))
5661         {
5662           operands[2] = GEN_INT (-INTVAL (operands[2]));
5663           return "sub{l}\t{%2, %k0|%k0, %2}";
5664         }
5665       return "add{l}\t{%2, %k0|%k0, %2}";
5666     }
5668   [(set (attr "type")
5669      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670         (const_string "incdec")
5671         (const_string "alu")))
5672    (set_attr "mode" "SI")])
5674 (define_insn "*addsi_3"
5675   [(set (reg FLAGS_REG)
5676         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5677                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5678    (clobber (match_scratch:SI 0 "=r"))]
5679   "ix86_match_ccmode (insn, CCZmode)
5680    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5681    /* Current assemblers are broken and do not allow @GOTOFF in
5682       ought but a memory context.  */
5683    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5685   switch (get_attr_type (insn))
5686     {
5687     case TYPE_INCDEC:
5688       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689       if (operands[2] == const1_rtx)
5690         return "inc{l}\t%0";
5691       else
5692         {
5693           gcc_assert (operands[2] == constm1_rtx);
5694           return "dec{l}\t%0";
5695         }
5697     default:
5698       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5700          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5701       if (CONST_INT_P (operands[2])
5702           && (INTVAL (operands[2]) == 128
5703               || (INTVAL (operands[2]) < 0
5704                   && INTVAL (operands[2]) != -128)))
5705         {
5706           operands[2] = GEN_INT (-INTVAL (operands[2]));
5707           return "sub{l}\t{%2, %0|%0, %2}";
5708         }
5709       return "add{l}\t{%2, %0|%0, %2}";
5710     }
5712   [(set (attr "type")
5713      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5714         (const_string "incdec")
5715         (const_string "alu")))
5716    (set_attr "mode" "SI")])
5718 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5719 (define_insn "*addsi_3_zext"
5720   [(set (reg FLAGS_REG)
5721         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5722                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5723    (set (match_operand:DI 0 "register_operand" "=r")
5724         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5725   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5726    && ix86_binary_operator_ok (PLUS, SImode, operands)
5727    /* Current assemblers are broken and do not allow @GOTOFF in
5728       ought but a memory context.  */
5729    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5731   switch (get_attr_type (insn))
5732     {
5733     case TYPE_INCDEC:
5734       if (operands[2] == const1_rtx)
5735         return "inc{l}\t%k0";
5736       else
5737         {
5738           gcc_assert (operands[2] == constm1_rtx);
5739           return "dec{l}\t%k0";
5740         }
5742     default:
5743       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5744          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5745       if (CONST_INT_P (operands[2])
5746           && (INTVAL (operands[2]) == 128
5747               || (INTVAL (operands[2]) < 0
5748                   && INTVAL (operands[2]) != -128)))
5749         {
5750           operands[2] = GEN_INT (-INTVAL (operands[2]));
5751           return "sub{l}\t{%2, %k0|%k0, %2}";
5752         }
5753       return "add{l}\t{%2, %k0|%k0, %2}";
5754     }
5756   [(set (attr "type")
5757      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5758         (const_string "incdec")
5759         (const_string "alu")))
5760    (set_attr "mode" "SI")])
5762 ; For comparisons against 1, -1 and 128, we may generate better code
5763 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5764 ; is matched then.  We can't accept general immediate, because for
5765 ; case of overflows,  the result is messed up.
5766 ; This pattern also don't hold of 0x80000000, since the value overflows
5767 ; when negated.
5768 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5769 ; only for comparisons not depending on it.
5770 (define_insn "*addsi_4"
5771   [(set (reg FLAGS_REG)
5772         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5773                  (match_operand:SI 2 "const_int_operand" "n")))
5774    (clobber (match_scratch:SI 0 "=rm"))]
5775   "ix86_match_ccmode (insn, CCGCmode)
5776    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5778   switch (get_attr_type (insn))
5779     {
5780     case TYPE_INCDEC:
5781       if (operands[2] == constm1_rtx)
5782         return "inc{l}\t%0";
5783       else
5784         {
5785           gcc_assert (operands[2] == const1_rtx);
5786           return "dec{l}\t%0";
5787         }
5789     default:
5790       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5791       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5792          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5793       if ((INTVAL (operands[2]) == -128
5794            || (INTVAL (operands[2]) > 0
5795                && INTVAL (operands[2]) != 128)))
5796         return "sub{l}\t{%2, %0|%0, %2}";
5797       operands[2] = GEN_INT (-INTVAL (operands[2]));
5798       return "add{l}\t{%2, %0|%0, %2}";
5799     }
5801   [(set (attr "type")
5802      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5803         (const_string "incdec")
5804         (const_string "alu")))
5805    (set_attr "mode" "SI")])
5807 (define_insn "*addsi_5"
5808   [(set (reg FLAGS_REG)
5809         (compare
5810           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5811                    (match_operand:SI 2 "general_operand" "rmni"))
5812           (const_int 0)))
5813    (clobber (match_scratch:SI 0 "=r"))]
5814   "ix86_match_ccmode (insn, CCGOCmode)
5815    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5816    /* Current assemblers are broken and do not allow @GOTOFF in
5817       ought but a memory context.  */
5818    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5820   switch (get_attr_type (insn))
5821     {
5822     case TYPE_INCDEC:
5823       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5824       if (operands[2] == const1_rtx)
5825         return "inc{l}\t%0";
5826       else
5827         {
5828           gcc_assert (operands[2] == constm1_rtx);
5829           return "dec{l}\t%0";
5830         }
5832     default:
5833       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5834       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5835          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5836       if (CONST_INT_P (operands[2])
5837           && (INTVAL (operands[2]) == 128
5838               || (INTVAL (operands[2]) < 0
5839                   && INTVAL (operands[2]) != -128)))
5840         {
5841           operands[2] = GEN_INT (-INTVAL (operands[2]));
5842           return "sub{l}\t{%2, %0|%0, %2}";
5843         }
5844       return "add{l}\t{%2, %0|%0, %2}";
5845     }
5847   [(set (attr "type")
5848      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5849         (const_string "incdec")
5850         (const_string "alu")))
5851    (set_attr "mode" "SI")])
5853 (define_expand "addhi3"
5854   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5855                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5856                             (match_operand:HI 2 "general_operand" "")))
5857               (clobber (reg:CC FLAGS_REG))])]
5858   "TARGET_HIMODE_MATH"
5859   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5861 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5862 ;; type optimizations enabled by define-splits.  This is not important
5863 ;; for PII, and in fact harmful because of partial register stalls.
5865 (define_insn "*addhi_1_lea"
5866   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5867         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5868                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5869    (clobber (reg:CC FLAGS_REG))]
5870   "!TARGET_PARTIAL_REG_STALL
5871    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5873   switch (get_attr_type (insn))
5874     {
5875     case TYPE_LEA:
5876       return "#";
5877     case TYPE_INCDEC:
5878       if (operands[2] == const1_rtx)
5879         return "inc{w}\t%0";
5880       else
5881         {
5882           gcc_assert (operands[2] == constm1_rtx);
5883           return "dec{w}\t%0";
5884         }
5886     default:
5887       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5888          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5889       if (CONST_INT_P (operands[2])
5890           && (INTVAL (operands[2]) == 128
5891               || (INTVAL (operands[2]) < 0
5892                   && INTVAL (operands[2]) != -128)))
5893         {
5894           operands[2] = GEN_INT (-INTVAL (operands[2]));
5895           return "sub{w}\t{%2, %0|%0, %2}";
5896         }
5897       return "add{w}\t{%2, %0|%0, %2}";
5898     }
5900   [(set (attr "type")
5901      (if_then_else (eq_attr "alternative" "2")
5902         (const_string "lea")
5903         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5904            (const_string "incdec")
5905            (const_string "alu"))))
5906    (set_attr "mode" "HI,HI,SI")])
5908 (define_insn "*addhi_1"
5909   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5910         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5911                  (match_operand:HI 2 "general_operand" "ri,rm")))
5912    (clobber (reg:CC FLAGS_REG))]
5913   "TARGET_PARTIAL_REG_STALL
5914    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5916   switch (get_attr_type (insn))
5917     {
5918     case TYPE_INCDEC:
5919       if (operands[2] == const1_rtx)
5920         return "inc{w}\t%0";
5921       else
5922         {
5923           gcc_assert (operands[2] == constm1_rtx);
5924           return "dec{w}\t%0";
5925         }
5927     default:
5928       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5929          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5930       if (CONST_INT_P (operands[2])
5931           && (INTVAL (operands[2]) == 128
5932               || (INTVAL (operands[2]) < 0
5933                   && INTVAL (operands[2]) != -128)))
5934         {
5935           operands[2] = GEN_INT (-INTVAL (operands[2]));
5936           return "sub{w}\t{%2, %0|%0, %2}";
5937         }
5938       return "add{w}\t{%2, %0|%0, %2}";
5939     }
5941   [(set (attr "type")
5942      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5943         (const_string "incdec")
5944         (const_string "alu")))
5945    (set_attr "mode" "HI")])
5947 (define_insn "*addhi_2"
5948   [(set (reg FLAGS_REG)
5949         (compare
5950           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5951                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5952           (const_int 0)))
5953    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5954         (plus:HI (match_dup 1) (match_dup 2)))]
5955   "ix86_match_ccmode (insn, CCGOCmode)
5956    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5958   switch (get_attr_type (insn))
5959     {
5960     case TYPE_INCDEC:
5961       if (operands[2] == const1_rtx)
5962         return "inc{w}\t%0";
5963       else
5964         {
5965           gcc_assert (operands[2] == constm1_rtx);
5966           return "dec{w}\t%0";
5967         }
5969     default:
5970       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5972       if (CONST_INT_P (operands[2])
5973           && (INTVAL (operands[2]) == 128
5974               || (INTVAL (operands[2]) < 0
5975                   && INTVAL (operands[2]) != -128)))
5976         {
5977           operands[2] = GEN_INT (-INTVAL (operands[2]));
5978           return "sub{w}\t{%2, %0|%0, %2}";
5979         }
5980       return "add{w}\t{%2, %0|%0, %2}";
5981     }
5983   [(set (attr "type")
5984      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5985         (const_string "incdec")
5986         (const_string "alu")))
5987    (set_attr "mode" "HI")])
5989 (define_insn "*addhi_3"
5990   [(set (reg FLAGS_REG)
5991         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5992                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5993    (clobber (match_scratch:HI 0 "=r"))]
5994   "ix86_match_ccmode (insn, CCZmode)
5995    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5997   switch (get_attr_type (insn))
5998     {
5999     case TYPE_INCDEC:
6000       if (operands[2] == const1_rtx)
6001         return "inc{w}\t%0";
6002       else
6003         {
6004           gcc_assert (operands[2] == constm1_rtx);
6005           return "dec{w}\t%0";
6006         }
6008     default:
6009       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6011       if (CONST_INT_P (operands[2])
6012           && (INTVAL (operands[2]) == 128
6013               || (INTVAL (operands[2]) < 0
6014                   && INTVAL (operands[2]) != -128)))
6015         {
6016           operands[2] = GEN_INT (-INTVAL (operands[2]));
6017           return "sub{w}\t{%2, %0|%0, %2}";
6018         }
6019       return "add{w}\t{%2, %0|%0, %2}";
6020     }
6022   [(set (attr "type")
6023      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6024         (const_string "incdec")
6025         (const_string "alu")))
6026    (set_attr "mode" "HI")])
6028 ; See comments above addsi_4 for details.
6029 (define_insn "*addhi_4"
6030   [(set (reg FLAGS_REG)
6031         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6032                  (match_operand:HI 2 "const_int_operand" "n")))
6033    (clobber (match_scratch:HI 0 "=rm"))]
6034   "ix86_match_ccmode (insn, CCGCmode)
6035    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6037   switch (get_attr_type (insn))
6038     {
6039     case TYPE_INCDEC:
6040       if (operands[2] == constm1_rtx)
6041         return "inc{w}\t%0";
6042       else
6043         {
6044           gcc_assert (operands[2] == const1_rtx);
6045           return "dec{w}\t%0";
6046         }
6048     default:
6049       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6050       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6051          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6052       if ((INTVAL (operands[2]) == -128
6053            || (INTVAL (operands[2]) > 0
6054                && INTVAL (operands[2]) != 128)))
6055         return "sub{w}\t{%2, %0|%0, %2}";
6056       operands[2] = GEN_INT (-INTVAL (operands[2]));
6057       return "add{w}\t{%2, %0|%0, %2}";
6058     }
6060   [(set (attr "type")
6061      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6062         (const_string "incdec")
6063         (const_string "alu")))
6064    (set_attr "mode" "SI")])
6067 (define_insn "*addhi_5"
6068   [(set (reg FLAGS_REG)
6069         (compare
6070           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6071                    (match_operand:HI 2 "general_operand" "rmni"))
6072           (const_int 0)))
6073    (clobber (match_scratch:HI 0 "=r"))]
6074   "ix86_match_ccmode (insn, CCGOCmode)
6075    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6077   switch (get_attr_type (insn))
6078     {
6079     case TYPE_INCDEC:
6080       if (operands[2] == const1_rtx)
6081         return "inc{w}\t%0";
6082       else
6083         {
6084           gcc_assert (operands[2] == constm1_rtx);
6085           return "dec{w}\t%0";
6086         }
6088     default:
6089       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6090          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6091       if (CONST_INT_P (operands[2])
6092           && (INTVAL (operands[2]) == 128
6093               || (INTVAL (operands[2]) < 0
6094                   && INTVAL (operands[2]) != -128)))
6095         {
6096           operands[2] = GEN_INT (-INTVAL (operands[2]));
6097           return "sub{w}\t{%2, %0|%0, %2}";
6098         }
6099       return "add{w}\t{%2, %0|%0, %2}";
6100     }
6102   [(set (attr "type")
6103      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6104         (const_string "incdec")
6105         (const_string "alu")))
6106    (set_attr "mode" "HI")])
6108 (define_expand "addqi3"
6109   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6110                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6111                             (match_operand:QI 2 "general_operand" "")))
6112               (clobber (reg:CC FLAGS_REG))])]
6113   "TARGET_QIMODE_MATH"
6114   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6116 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6117 (define_insn "*addqi_1_lea"
6118   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6119         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6120                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6121    (clobber (reg:CC FLAGS_REG))]
6122   "!TARGET_PARTIAL_REG_STALL
6123    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6125   int widen = (which_alternative == 2);
6126   switch (get_attr_type (insn))
6127     {
6128     case TYPE_LEA:
6129       return "#";
6130     case TYPE_INCDEC:
6131       if (operands[2] == const1_rtx)
6132         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6133       else
6134         {
6135           gcc_assert (operands[2] == constm1_rtx);
6136           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6137         }
6139     default:
6140       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6142       if (CONST_INT_P (operands[2])
6143           && (INTVAL (operands[2]) == 128
6144               || (INTVAL (operands[2]) < 0
6145                   && INTVAL (operands[2]) != -128)))
6146         {
6147           operands[2] = GEN_INT (-INTVAL (operands[2]));
6148           if (widen)
6149             return "sub{l}\t{%2, %k0|%k0, %2}";
6150           else
6151             return "sub{b}\t{%2, %0|%0, %2}";
6152         }
6153       if (widen)
6154         return "add{l}\t{%k2, %k0|%k0, %k2}";
6155       else
6156         return "add{b}\t{%2, %0|%0, %2}";
6157     }
6159   [(set (attr "type")
6160      (if_then_else (eq_attr "alternative" "3")
6161         (const_string "lea")
6162         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6163            (const_string "incdec")
6164            (const_string "alu"))))
6165    (set_attr "mode" "QI,QI,SI,SI")])
6167 (define_insn "*addqi_1"
6168   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6169         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6170                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6171    (clobber (reg:CC FLAGS_REG))]
6172   "TARGET_PARTIAL_REG_STALL
6173    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6175   int widen = (which_alternative == 2);
6176   switch (get_attr_type (insn))
6177     {
6178     case TYPE_INCDEC:
6179       if (operands[2] == const1_rtx)
6180         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6181       else
6182         {
6183           gcc_assert (operands[2] == constm1_rtx);
6184           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6185         }
6187     default:
6188       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6189          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6190       if (CONST_INT_P (operands[2])
6191           && (INTVAL (operands[2]) == 128
6192               || (INTVAL (operands[2]) < 0
6193                   && INTVAL (operands[2]) != -128)))
6194         {
6195           operands[2] = GEN_INT (-INTVAL (operands[2]));
6196           if (widen)
6197             return "sub{l}\t{%2, %k0|%k0, %2}";
6198           else
6199             return "sub{b}\t{%2, %0|%0, %2}";
6200         }
6201       if (widen)
6202         return "add{l}\t{%k2, %k0|%k0, %k2}";
6203       else
6204         return "add{b}\t{%2, %0|%0, %2}";
6205     }
6207   [(set (attr "type")
6208      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6209         (const_string "incdec")
6210         (const_string "alu")))
6211    (set_attr "mode" "QI,QI,SI")])
6213 (define_insn "*addqi_1_slp"
6214   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6215         (plus:QI (match_dup 0)
6216                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6217    (clobber (reg:CC FLAGS_REG))]
6218   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6219    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6221   switch (get_attr_type (insn))
6222     {
6223     case TYPE_INCDEC:
6224       if (operands[1] == const1_rtx)
6225         return "inc{b}\t%0";
6226       else
6227         {
6228           gcc_assert (operands[1] == constm1_rtx);
6229           return "dec{b}\t%0";
6230         }
6232     default:
6233       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6234       if (CONST_INT_P (operands[1])
6235           && INTVAL (operands[1]) < 0)
6236         {
6237           operands[1] = GEN_INT (-INTVAL (operands[1]));
6238           return "sub{b}\t{%1, %0|%0, %1}";
6239         }
6240       return "add{b}\t{%1, %0|%0, %1}";
6241     }
6243   [(set (attr "type")
6244      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6245         (const_string "incdec")
6246         (const_string "alu1")))
6247    (set (attr "memory")
6248      (if_then_else (match_operand 1 "memory_operand" "")
6249         (const_string "load")
6250         (const_string "none")))
6251    (set_attr "mode" "QI")])
6253 (define_insn "*addqi_2"
6254   [(set (reg FLAGS_REG)
6255         (compare
6256           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6257                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6258           (const_int 0)))
6259    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6260         (plus:QI (match_dup 1) (match_dup 2)))]
6261   "ix86_match_ccmode (insn, CCGOCmode)
6262    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6264   switch (get_attr_type (insn))
6265     {
6266     case TYPE_INCDEC:
6267       if (operands[2] == const1_rtx)
6268         return "inc{b}\t%0";
6269       else
6270         {
6271           gcc_assert (operands[2] == constm1_rtx
6272                       || (CONST_INT_P (operands[2])
6273                           && INTVAL (operands[2]) == 255));
6274           return "dec{b}\t%0";
6275         }
6277     default:
6278       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6279       if (CONST_INT_P (operands[2])
6280           && INTVAL (operands[2]) < 0)
6281         {
6282           operands[2] = GEN_INT (-INTVAL (operands[2]));
6283           return "sub{b}\t{%2, %0|%0, %2}";
6284         }
6285       return "add{b}\t{%2, %0|%0, %2}";
6286     }
6288   [(set (attr "type")
6289      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6290         (const_string "incdec")
6291         (const_string "alu")))
6292    (set_attr "mode" "QI")])
6294 (define_insn "*addqi_3"
6295   [(set (reg FLAGS_REG)
6296         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6297                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6298    (clobber (match_scratch:QI 0 "=q"))]
6299   "ix86_match_ccmode (insn, CCZmode)
6300    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6302   switch (get_attr_type (insn))
6303     {
6304     case TYPE_INCDEC:
6305       if (operands[2] == const1_rtx)
6306         return "inc{b}\t%0";
6307       else
6308         {
6309           gcc_assert (operands[2] == constm1_rtx
6310                       || (CONST_INT_P (operands[2])
6311                           && INTVAL (operands[2]) == 255));
6312           return "dec{b}\t%0";
6313         }
6315     default:
6316       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6317       if (CONST_INT_P (operands[2])
6318           && INTVAL (operands[2]) < 0)
6319         {
6320           operands[2] = GEN_INT (-INTVAL (operands[2]));
6321           return "sub{b}\t{%2, %0|%0, %2}";
6322         }
6323       return "add{b}\t{%2, %0|%0, %2}";
6324     }
6326   [(set (attr "type")
6327      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6328         (const_string "incdec")
6329         (const_string "alu")))
6330    (set_attr "mode" "QI")])
6332 ; See comments above addsi_4 for details.
6333 (define_insn "*addqi_4"
6334   [(set (reg FLAGS_REG)
6335         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6336                  (match_operand:QI 2 "const_int_operand" "n")))
6337    (clobber (match_scratch:QI 0 "=qm"))]
6338   "ix86_match_ccmode (insn, CCGCmode)
6339    && (INTVAL (operands[2]) & 0xff) != 0x80"
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       if (operands[2] == constm1_rtx
6345           || (CONST_INT_P (operands[2])
6346               && INTVAL (operands[2]) == 255))
6347         return "inc{b}\t%0";
6348       else
6349         {
6350           gcc_assert (operands[2] == const1_rtx);
6351           return "dec{b}\t%0";
6352         }
6354     default:
6355       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6356       if (INTVAL (operands[2]) < 0)
6357         {
6358           operands[2] = GEN_INT (-INTVAL (operands[2]));
6359           return "add{b}\t{%2, %0|%0, %2}";
6360         }
6361       return "sub{b}\t{%2, %0|%0, %2}";
6362     }
6364   [(set (attr "type")
6365      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6366         (const_string "incdec")
6367         (const_string "alu")))
6368    (set_attr "mode" "QI")])
6371 (define_insn "*addqi_5"
6372   [(set (reg FLAGS_REG)
6373         (compare
6374           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6375                    (match_operand:QI 2 "general_operand" "qmni"))
6376           (const_int 0)))
6377    (clobber (match_scratch:QI 0 "=q"))]
6378   "ix86_match_ccmode (insn, CCGOCmode)
6379    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6381   switch (get_attr_type (insn))
6382     {
6383     case TYPE_INCDEC:
6384       if (operands[2] == const1_rtx)
6385         return "inc{b}\t%0";
6386       else
6387         {
6388           gcc_assert (operands[2] == constm1_rtx
6389                       || (CONST_INT_P (operands[2])
6390                           && INTVAL (operands[2]) == 255));
6391           return "dec{b}\t%0";
6392         }
6394     default:
6395       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6396       if (CONST_INT_P (operands[2])
6397           && INTVAL (operands[2]) < 0)
6398         {
6399           operands[2] = GEN_INT (-INTVAL (operands[2]));
6400           return "sub{b}\t{%2, %0|%0, %2}";
6401         }
6402       return "add{b}\t{%2, %0|%0, %2}";
6403     }
6405   [(set (attr "type")
6406      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407         (const_string "incdec")
6408         (const_string "alu")))
6409    (set_attr "mode" "QI")])
6412 (define_insn "addqi_ext_1"
6413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6414                          (const_int 8)
6415                          (const_int 8))
6416         (plus:SI
6417           (zero_extract:SI
6418             (match_operand 1 "ext_register_operand" "0")
6419             (const_int 8)
6420             (const_int 8))
6421           (match_operand:QI 2 "general_operand" "Qmn")))
6422    (clobber (reg:CC FLAGS_REG))]
6423   "!TARGET_64BIT"
6425   switch (get_attr_type (insn))
6426     {
6427     case TYPE_INCDEC:
6428       if (operands[2] == const1_rtx)
6429         return "inc{b}\t%h0";
6430       else
6431         {
6432           gcc_assert (operands[2] == constm1_rtx
6433                       || (CONST_INT_P (operands[2])
6434                           && INTVAL (operands[2]) == 255));
6435           return "dec{b}\t%h0";
6436         }
6438     default:
6439       return "add{b}\t{%2, %h0|%h0, %2}";
6440     }
6442   [(set (attr "type")
6443      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6444         (const_string "incdec")
6445         (const_string "alu")))
6446    (set_attr "mode" "QI")])
6448 (define_insn "*addqi_ext_1_rex64"
6449   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6450                          (const_int 8)
6451                          (const_int 8))
6452         (plus:SI
6453           (zero_extract:SI
6454             (match_operand 1 "ext_register_operand" "0")
6455             (const_int 8)
6456             (const_int 8))
6457           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6458    (clobber (reg:CC FLAGS_REG))]
6459   "TARGET_64BIT"
6461   switch (get_attr_type (insn))
6462     {
6463     case TYPE_INCDEC:
6464       if (operands[2] == const1_rtx)
6465         return "inc{b}\t%h0";
6466       else
6467         {
6468           gcc_assert (operands[2] == constm1_rtx
6469                       || (CONST_INT_P (operands[2])
6470                           && INTVAL (operands[2]) == 255));
6471           return "dec{b}\t%h0";
6472         }
6474     default:
6475       return "add{b}\t{%2, %h0|%h0, %2}";
6476     }
6478   [(set (attr "type")
6479      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6480         (const_string "incdec")
6481         (const_string "alu")))
6482    (set_attr "mode" "QI")])
6484 (define_insn "*addqi_ext_2"
6485   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6486                          (const_int 8)
6487                          (const_int 8))
6488         (plus:SI
6489           (zero_extract:SI
6490             (match_operand 1 "ext_register_operand" "%0")
6491             (const_int 8)
6492             (const_int 8))
6493           (zero_extract:SI
6494             (match_operand 2 "ext_register_operand" "Q")
6495             (const_int 8)
6496             (const_int 8))))
6497    (clobber (reg:CC FLAGS_REG))]
6498   ""
6499   "add{b}\t{%h2, %h0|%h0, %h2}"
6500   [(set_attr "type" "alu")
6501    (set_attr "mode" "QI")])
6503 ;; The patterns that match these are at the end of this file.
6505 (define_expand "addxf3"
6506   [(set (match_operand:XF 0 "register_operand" "")
6507         (plus:XF (match_operand:XF 1 "register_operand" "")
6508                  (match_operand:XF 2 "register_operand" "")))]
6509   "TARGET_80387"
6510   "")
6512 (define_expand "adddf3"
6513   [(set (match_operand:DF 0 "register_operand" "")
6514         (plus:DF (match_operand:DF 1 "register_operand" "")
6515                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6516   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6517   "")
6519 (define_expand "addsf3"
6520   [(set (match_operand:SF 0 "register_operand" "")
6521         (plus:SF (match_operand:SF 1 "register_operand" "")
6522                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6523   "TARGET_80387 || TARGET_SSE_MATH"
6524   "")
6526 ;; Subtract instructions
6528 ;; %%% splits for subditi3
6530 (define_expand "subti3"
6531   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6532                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6533                              (match_operand:TI 2 "x86_64_general_operand" "")))
6534               (clobber (reg:CC FLAGS_REG))])]
6535   "TARGET_64BIT"
6536   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6538 (define_insn "*subti3_1"
6539   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6540         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6541                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6542    (clobber (reg:CC FLAGS_REG))]
6543   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6544   "#")
6546 (define_split
6547   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6548         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6549                   (match_operand:TI 2 "general_operand" "")))
6550    (clobber (reg:CC FLAGS_REG))]
6551   "TARGET_64BIT && reload_completed"
6552   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6553               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6554    (parallel [(set (match_dup 3)
6555                    (minus:DI (match_dup 4)
6556                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6557                                       (match_dup 5))))
6558               (clobber (reg:CC FLAGS_REG))])]
6559   "split_ti (operands+0, 1, operands+0, operands+3);
6560    split_ti (operands+1, 1, operands+1, operands+4);
6561    split_ti (operands+2, 1, operands+2, operands+5);")
6563 ;; %%% splits for subsidi3
6565 (define_expand "subdi3"
6566   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6567                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6568                              (match_operand:DI 2 "x86_64_general_operand" "")))
6569               (clobber (reg:CC FLAGS_REG))])]
6570   ""
6571   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6573 (define_insn "*subdi3_1"
6574   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6575         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6576                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6577    (clobber (reg:CC FLAGS_REG))]
6578   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6579   "#")
6581 (define_split
6582   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6583         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6584                   (match_operand:DI 2 "general_operand" "")))
6585    (clobber (reg:CC FLAGS_REG))]
6586   "!TARGET_64BIT && reload_completed"
6587   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6588               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6589    (parallel [(set (match_dup 3)
6590                    (minus:SI (match_dup 4)
6591                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6592                                       (match_dup 5))))
6593               (clobber (reg:CC FLAGS_REG))])]
6594   "split_di (operands+0, 1, operands+0, operands+3);
6595    split_di (operands+1, 1, operands+1, operands+4);
6596    split_di (operands+2, 1, operands+2, operands+5);")
6598 (define_insn "subdi3_carry_rex64"
6599   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6600           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6601             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6602                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6603    (clobber (reg:CC FLAGS_REG))]
6604   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6605   "sbb{q}\t{%2, %0|%0, %2}"
6606   [(set_attr "type" "alu")
6607    (set_attr "pent_pair" "pu")
6608    (set_attr "mode" "DI")])
6610 (define_insn "*subdi_1_rex64"
6611   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6612         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6613                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6614    (clobber (reg:CC FLAGS_REG))]
6615   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6616   "sub{q}\t{%2, %0|%0, %2}"
6617   [(set_attr "type" "alu")
6618    (set_attr "mode" "DI")])
6620 (define_insn "*subdi_2_rex64"
6621   [(set (reg FLAGS_REG)
6622         (compare
6623           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6624                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6625           (const_int 0)))
6626    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6627         (minus:DI (match_dup 1) (match_dup 2)))]
6628   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6629    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6630   "sub{q}\t{%2, %0|%0, %2}"
6631   [(set_attr "type" "alu")
6632    (set_attr "mode" "DI")])
6634 (define_insn "*subdi_3_rex63"
6635   [(set (reg FLAGS_REG)
6636         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6637                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6638    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6639         (minus:DI (match_dup 1) (match_dup 2)))]
6640   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6641    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6642   "sub{q}\t{%2, %0|%0, %2}"
6643   [(set_attr "type" "alu")
6644    (set_attr "mode" "DI")])
6646 (define_insn "subqi3_carry"
6647   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6648           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6649             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6650                (match_operand:QI 2 "general_operand" "qi,qm"))))
6651    (clobber (reg:CC FLAGS_REG))]
6652   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6653   "sbb{b}\t{%2, %0|%0, %2}"
6654   [(set_attr "type" "alu")
6655    (set_attr "pent_pair" "pu")
6656    (set_attr "mode" "QI")])
6658 (define_insn "subhi3_carry"
6659   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6660           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6661             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6662                (match_operand:HI 2 "general_operand" "ri,rm"))))
6663    (clobber (reg:CC FLAGS_REG))]
6664   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6665   "sbb{w}\t{%2, %0|%0, %2}"
6666   [(set_attr "type" "alu")
6667    (set_attr "pent_pair" "pu")
6668    (set_attr "mode" "HI")])
6670 (define_insn "subsi3_carry"
6671   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6672           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6674                (match_operand:SI 2 "general_operand" "ri,rm"))))
6675    (clobber (reg:CC FLAGS_REG))]
6676   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6677   "sbb{l}\t{%2, %0|%0, %2}"
6678   [(set_attr "type" "alu")
6679    (set_attr "pent_pair" "pu")
6680    (set_attr "mode" "SI")])
6682 (define_insn "subsi3_carry_zext"
6683   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6684           (zero_extend:DI
6685             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6686               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6687                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6688    (clobber (reg:CC FLAGS_REG))]
6689   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6690   "sbb{l}\t{%2, %k0|%k0, %2}"
6691   [(set_attr "type" "alu")
6692    (set_attr "pent_pair" "pu")
6693    (set_attr "mode" "SI")])
6695 (define_expand "subsi3"
6696   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6697                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6698                              (match_operand:SI 2 "general_operand" "")))
6699               (clobber (reg:CC FLAGS_REG))])]
6700   ""
6701   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6703 (define_insn "*subsi_1"
6704   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6705         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6706                   (match_operand:SI 2 "general_operand" "ri,rm")))
6707    (clobber (reg:CC FLAGS_REG))]
6708   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6709   "sub{l}\t{%2, %0|%0, %2}"
6710   [(set_attr "type" "alu")
6711    (set_attr "mode" "SI")])
6713 (define_insn "*subsi_1_zext"
6714   [(set (match_operand:DI 0 "register_operand" "=r")
6715         (zero_extend:DI
6716           (minus:SI (match_operand:SI 1 "register_operand" "0")
6717                     (match_operand:SI 2 "general_operand" "rim"))))
6718    (clobber (reg:CC FLAGS_REG))]
6719   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6720   "sub{l}\t{%2, %k0|%k0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "mode" "SI")])
6724 (define_insn "*subsi_2"
6725   [(set (reg FLAGS_REG)
6726         (compare
6727           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6728                     (match_operand:SI 2 "general_operand" "ri,rm"))
6729           (const_int 0)))
6730    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6731         (minus:SI (match_dup 1) (match_dup 2)))]
6732   "ix86_match_ccmode (insn, CCGOCmode)
6733    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6734   "sub{l}\t{%2, %0|%0, %2}"
6735   [(set_attr "type" "alu")
6736    (set_attr "mode" "SI")])
6738 (define_insn "*subsi_2_zext"
6739   [(set (reg FLAGS_REG)
6740         (compare
6741           (minus:SI (match_operand:SI 1 "register_operand" "0")
6742                     (match_operand:SI 2 "general_operand" "rim"))
6743           (const_int 0)))
6744    (set (match_operand:DI 0 "register_operand" "=r")
6745         (zero_extend:DI
6746           (minus:SI (match_dup 1)
6747                     (match_dup 2))))]
6748   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6749    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6750   "sub{l}\t{%2, %k0|%k0, %2}"
6751   [(set_attr "type" "alu")
6752    (set_attr "mode" "SI")])
6754 (define_insn "*subsi_3"
6755   [(set (reg FLAGS_REG)
6756         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6757                  (match_operand:SI 2 "general_operand" "ri,rm")))
6758    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6759         (minus:SI (match_dup 1) (match_dup 2)))]
6760   "ix86_match_ccmode (insn, CCmode)
6761    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6762   "sub{l}\t{%2, %0|%0, %2}"
6763   [(set_attr "type" "alu")
6764    (set_attr "mode" "SI")])
6766 (define_insn "*subsi_3_zext"
6767   [(set (reg FLAGS_REG)
6768         (compare (match_operand:SI 1 "register_operand" "0")
6769                  (match_operand:SI 2 "general_operand" "rim")))
6770    (set (match_operand:DI 0 "register_operand" "=r")
6771         (zero_extend:DI
6772           (minus:SI (match_dup 1)
6773                     (match_dup 2))))]
6774   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6775    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6776   "sub{l}\t{%2, %1|%1, %2}"
6777   [(set_attr "type" "alu")
6778    (set_attr "mode" "DI")])
6780 (define_expand "subhi3"
6781   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6782                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6783                              (match_operand:HI 2 "general_operand" "")))
6784               (clobber (reg:CC FLAGS_REG))])]
6785   "TARGET_HIMODE_MATH"
6786   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6788 (define_insn "*subhi_1"
6789   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6790         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6791                   (match_operand:HI 2 "general_operand" "ri,rm")))
6792    (clobber (reg:CC FLAGS_REG))]
6793   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6794   "sub{w}\t{%2, %0|%0, %2}"
6795   [(set_attr "type" "alu")
6796    (set_attr "mode" "HI")])
6798 (define_insn "*subhi_2"
6799   [(set (reg FLAGS_REG)
6800         (compare
6801           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6802                     (match_operand:HI 2 "general_operand" "ri,rm"))
6803           (const_int 0)))
6804    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6805         (minus:HI (match_dup 1) (match_dup 2)))]
6806   "ix86_match_ccmode (insn, CCGOCmode)
6807    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6808   "sub{w}\t{%2, %0|%0, %2}"
6809   [(set_attr "type" "alu")
6810    (set_attr "mode" "HI")])
6812 (define_insn "*subhi_3"
6813   [(set (reg FLAGS_REG)
6814         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6815                  (match_operand:HI 2 "general_operand" "ri,rm")))
6816    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6817         (minus:HI (match_dup 1) (match_dup 2)))]
6818   "ix86_match_ccmode (insn, CCmode)
6819    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6820   "sub{w}\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "alu")
6822    (set_attr "mode" "HI")])
6824 (define_expand "subqi3"
6825   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6826                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6827                              (match_operand:QI 2 "general_operand" "")))
6828               (clobber (reg:CC FLAGS_REG))])]
6829   "TARGET_QIMODE_MATH"
6830   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6832 (define_insn "*subqi_1"
6833   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6834         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6835                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6836    (clobber (reg:CC FLAGS_REG))]
6837   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6838   "sub{b}\t{%2, %0|%0, %2}"
6839   [(set_attr "type" "alu")
6840    (set_attr "mode" "QI")])
6842 (define_insn "*subqi_1_slp"
6843   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6844         (minus:QI (match_dup 0)
6845                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6846    (clobber (reg:CC FLAGS_REG))]
6847   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6848    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6849   "sub{b}\t{%1, %0|%0, %1}"
6850   [(set_attr "type" "alu1")
6851    (set_attr "mode" "QI")])
6853 (define_insn "*subqi_2"
6854   [(set (reg FLAGS_REG)
6855         (compare
6856           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6857                     (match_operand:QI 2 "general_operand" "qi,qm"))
6858           (const_int 0)))
6859    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6860         (minus:HI (match_dup 1) (match_dup 2)))]
6861   "ix86_match_ccmode (insn, CCGOCmode)
6862    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6863   "sub{b}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "alu")
6865    (set_attr "mode" "QI")])
6867 (define_insn "*subqi_3"
6868   [(set (reg FLAGS_REG)
6869         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6870                  (match_operand:QI 2 "general_operand" "qi,qm")))
6871    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6872         (minus:HI (match_dup 1) (match_dup 2)))]
6873   "ix86_match_ccmode (insn, CCmode)
6874    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6875   "sub{b}\t{%2, %0|%0, %2}"
6876   [(set_attr "type" "alu")
6877    (set_attr "mode" "QI")])
6879 ;; The patterns that match these are at the end of this file.
6881 (define_expand "subxf3"
6882   [(set (match_operand:XF 0 "register_operand" "")
6883         (minus:XF (match_operand:XF 1 "register_operand" "")
6884                   (match_operand:XF 2 "register_operand" "")))]
6885   "TARGET_80387"
6886   "")
6888 (define_expand "subdf3"
6889   [(set (match_operand:DF 0 "register_operand" "")
6890         (minus:DF (match_operand:DF 1 "register_operand" "")
6891                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6892   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6893   "")
6895 (define_expand "subsf3"
6896   [(set (match_operand:SF 0 "register_operand" "")
6897         (minus:SF (match_operand:SF 1 "register_operand" "")
6898                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6899   "TARGET_80387 || TARGET_SSE_MATH"
6900   "")
6902 ;; Multiply instructions
6904 (define_expand "muldi3"
6905   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6906                    (mult:DI (match_operand:DI 1 "register_operand" "")
6907                             (match_operand:DI 2 "x86_64_general_operand" "")))
6908               (clobber (reg:CC FLAGS_REG))])]
6909   "TARGET_64BIT"
6910   "")
6912 (define_insn "*muldi3_1_rex64"
6913   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6914         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6915                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "TARGET_64BIT
6918    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6919   "@
6920    imul{q}\t{%2, %1, %0|%0, %1, %2}
6921    imul{q}\t{%2, %1, %0|%0, %1, %2}
6922    imul{q}\t{%2, %0|%0, %2}"
6923   [(set_attr "type" "imul")
6924    (set_attr "prefix_0f" "0,0,1")
6925    (set (attr "athlon_decode")
6926         (cond [(eq_attr "cpu" "athlon")
6927                   (const_string "vector")
6928                (eq_attr "alternative" "1")
6929                   (const_string "vector")
6930                (and (eq_attr "alternative" "2")
6931                     (match_operand 1 "memory_operand" ""))
6932                   (const_string "vector")]
6933               (const_string "direct")))
6934    (set_attr "mode" "DI")])
6936 (define_expand "mulsi3"
6937   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6938                    (mult:SI (match_operand:SI 1 "register_operand" "")
6939                             (match_operand:SI 2 "general_operand" "")))
6940               (clobber (reg:CC FLAGS_REG))])]
6941   ""
6942   "")
6944 (define_insn "*mulsi3_1"
6945   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6946         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6947                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6948    (clobber (reg:CC FLAGS_REG))]
6949   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950   "@
6951    imul{l}\t{%2, %1, %0|%0, %1, %2}
6952    imul{l}\t{%2, %1, %0|%0, %1, %2}
6953    imul{l}\t{%2, %0|%0, %2}"
6954   [(set_attr "type" "imul")
6955    (set_attr "prefix_0f" "0,0,1")
6956    (set (attr "athlon_decode")
6957         (cond [(eq_attr "cpu" "athlon")
6958                   (const_string "vector")
6959                (eq_attr "alternative" "1")
6960                   (const_string "vector")
6961                (and (eq_attr "alternative" "2")
6962                     (match_operand 1 "memory_operand" ""))
6963                   (const_string "vector")]
6964               (const_string "direct")))
6965    (set_attr "mode" "SI")])
6967 (define_insn "*mulsi3_1_zext"
6968   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6969         (zero_extend:DI
6970           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6971                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6972    (clobber (reg:CC FLAGS_REG))]
6973   "TARGET_64BIT
6974    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6975   "@
6976    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6977    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6978    imul{l}\t{%2, %k0|%k0, %2}"
6979   [(set_attr "type" "imul")
6980    (set_attr "prefix_0f" "0,0,1")
6981    (set (attr "athlon_decode")
6982         (cond [(eq_attr "cpu" "athlon")
6983                   (const_string "vector")
6984                (eq_attr "alternative" "1")
6985                   (const_string "vector")
6986                (and (eq_attr "alternative" "2")
6987                     (match_operand 1 "memory_operand" ""))
6988                   (const_string "vector")]
6989               (const_string "direct")))
6990    (set_attr "mode" "SI")])
6992 (define_expand "mulhi3"
6993   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6994                    (mult:HI (match_operand:HI 1 "register_operand" "")
6995                             (match_operand:HI 2 "general_operand" "")))
6996               (clobber (reg:CC FLAGS_REG))])]
6997   "TARGET_HIMODE_MATH"
6998   "")
7000 (define_insn "*mulhi3_1"
7001   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7002         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7003                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7004    (clobber (reg:CC FLAGS_REG))]
7005   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7006   "@
7007    imul{w}\t{%2, %1, %0|%0, %1, %2}
7008    imul{w}\t{%2, %1, %0|%0, %1, %2}
7009    imul{w}\t{%2, %0|%0, %2}"
7010   [(set_attr "type" "imul")
7011    (set_attr "prefix_0f" "0,0,1")
7012    (set (attr "athlon_decode")
7013         (cond [(eq_attr "cpu" "athlon")
7014                   (const_string "vector")
7015                (eq_attr "alternative" "1,2")
7016                   (const_string "vector")]
7017               (const_string "direct")))
7018    (set_attr "mode" "HI")])
7020 (define_expand "mulqi3"
7021   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7022                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7023                             (match_operand:QI 2 "register_operand" "")))
7024               (clobber (reg:CC FLAGS_REG))])]
7025   "TARGET_QIMODE_MATH"
7026   "")
7028 (define_insn "*mulqi3_1"
7029   [(set (match_operand:QI 0 "register_operand" "=a")
7030         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7031                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7032    (clobber (reg:CC FLAGS_REG))]
7033   "TARGET_QIMODE_MATH
7034    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7035   "mul{b}\t%2"
7036   [(set_attr "type" "imul")
7037    (set_attr "length_immediate" "0")
7038    (set (attr "athlon_decode")
7039      (if_then_else (eq_attr "cpu" "athlon")
7040         (const_string "vector")
7041         (const_string "direct")))
7042    (set_attr "mode" "QI")])
7044 (define_expand "umulqihi3"
7045   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7046                    (mult:HI (zero_extend:HI
7047                               (match_operand:QI 1 "nonimmediate_operand" ""))
7048                             (zero_extend:HI
7049                               (match_operand:QI 2 "register_operand" ""))))
7050               (clobber (reg:CC FLAGS_REG))])]
7051   "TARGET_QIMODE_MATH"
7052   "")
7054 (define_insn "*umulqihi3_1"
7055   [(set (match_operand:HI 0 "register_operand" "=a")
7056         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7057                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7058    (clobber (reg:CC FLAGS_REG))]
7059   "TARGET_QIMODE_MATH
7060    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7061   "mul{b}\t%2"
7062   [(set_attr "type" "imul")
7063    (set_attr "length_immediate" "0")
7064    (set (attr "athlon_decode")
7065      (if_then_else (eq_attr "cpu" "athlon")
7066         (const_string "vector")
7067         (const_string "direct")))
7068    (set_attr "mode" "QI")])
7070 (define_expand "mulqihi3"
7071   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7072                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7073                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7074               (clobber (reg:CC FLAGS_REG))])]
7075   "TARGET_QIMODE_MATH"
7076   "")
7078 (define_insn "*mulqihi3_insn"
7079   [(set (match_operand:HI 0 "register_operand" "=a")
7080         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7081                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7082    (clobber (reg:CC FLAGS_REG))]
7083   "TARGET_QIMODE_MATH
7084    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7085   "imul{b}\t%2"
7086   [(set_attr "type" "imul")
7087    (set_attr "length_immediate" "0")
7088    (set (attr "athlon_decode")
7089      (if_then_else (eq_attr "cpu" "athlon")
7090         (const_string "vector")
7091         (const_string "direct")))
7092    (set_attr "mode" "QI")])
7094 (define_expand "umulditi3"
7095   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7096                    (mult:TI (zero_extend:TI
7097                               (match_operand:DI 1 "nonimmediate_operand" ""))
7098                             (zero_extend:TI
7099                               (match_operand:DI 2 "register_operand" ""))))
7100               (clobber (reg:CC FLAGS_REG))])]
7101   "TARGET_64BIT"
7102   "")
7104 (define_insn "*umulditi3_insn"
7105   [(set (match_operand:TI 0 "register_operand" "=A")
7106         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7107                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7108    (clobber (reg:CC FLAGS_REG))]
7109   "TARGET_64BIT
7110    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7111   "mul{q}\t%2"
7112   [(set_attr "type" "imul")
7113    (set_attr "length_immediate" "0")
7114    (set (attr "athlon_decode")
7115      (if_then_else (eq_attr "cpu" "athlon")
7116         (const_string "vector")
7117         (const_string "double")))
7118    (set_attr "mode" "DI")])
7120 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7121 (define_expand "umulsidi3"
7122   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7123                    (mult:DI (zero_extend:DI
7124                               (match_operand:SI 1 "nonimmediate_operand" ""))
7125                             (zero_extend:DI
7126                               (match_operand:SI 2 "register_operand" ""))))
7127               (clobber (reg:CC FLAGS_REG))])]
7128   "!TARGET_64BIT"
7129   "")
7131 (define_insn "*umulsidi3_insn"
7132   [(set (match_operand:DI 0 "register_operand" "=A")
7133         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7134                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7135    (clobber (reg:CC FLAGS_REG))]
7136   "!TARGET_64BIT
7137    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7138   "mul{l}\t%2"
7139   [(set_attr "type" "imul")
7140    (set_attr "length_immediate" "0")
7141    (set (attr "athlon_decode")
7142      (if_then_else (eq_attr "cpu" "athlon")
7143         (const_string "vector")
7144         (const_string "double")))
7145    (set_attr "mode" "SI")])
7147 (define_expand "mulditi3"
7148   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7149                    (mult:TI (sign_extend:TI
7150                               (match_operand:DI 1 "nonimmediate_operand" ""))
7151                             (sign_extend:TI
7152                               (match_operand:DI 2 "register_operand" ""))))
7153               (clobber (reg:CC FLAGS_REG))])]
7154   "TARGET_64BIT"
7155   "")
7157 (define_insn "*mulditi3_insn"
7158   [(set (match_operand:TI 0 "register_operand" "=A")
7159         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7160                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7161    (clobber (reg:CC FLAGS_REG))]
7162   "TARGET_64BIT
7163    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7164   "imul{q}\t%2"
7165   [(set_attr "type" "imul")
7166    (set_attr "length_immediate" "0")
7167    (set (attr "athlon_decode")
7168      (if_then_else (eq_attr "cpu" "athlon")
7169         (const_string "vector")
7170         (const_string "double")))
7171    (set_attr "mode" "DI")])
7173 (define_expand "mulsidi3"
7174   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7175                    (mult:DI (sign_extend:DI
7176                               (match_operand:SI 1 "nonimmediate_operand" ""))
7177                             (sign_extend:DI
7178                               (match_operand:SI 2 "register_operand" ""))))
7179               (clobber (reg:CC FLAGS_REG))])]
7180   "!TARGET_64BIT"
7181   "")
7183 (define_insn "*mulsidi3_insn"
7184   [(set (match_operand:DI 0 "register_operand" "=A")
7185         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7186                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7187    (clobber (reg:CC FLAGS_REG))]
7188   "!TARGET_64BIT
7189    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7190   "imul{l}\t%2"
7191   [(set_attr "type" "imul")
7192    (set_attr "length_immediate" "0")
7193    (set (attr "athlon_decode")
7194      (if_then_else (eq_attr "cpu" "athlon")
7195         (const_string "vector")
7196         (const_string "double")))
7197    (set_attr "mode" "SI")])
7199 (define_expand "umuldi3_highpart"
7200   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7201                    (truncate:DI
7202                      (lshiftrt:TI
7203                        (mult:TI (zero_extend:TI
7204                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7205                                 (zero_extend:TI
7206                                   (match_operand:DI 2 "register_operand" "")))
7207                        (const_int 64))))
7208               (clobber (match_scratch:DI 3 ""))
7209               (clobber (reg:CC FLAGS_REG))])]
7210   "TARGET_64BIT"
7211   "")
7213 (define_insn "*umuldi3_highpart_rex64"
7214   [(set (match_operand:DI 0 "register_operand" "=d")
7215         (truncate:DI
7216           (lshiftrt:TI
7217             (mult:TI (zero_extend:TI
7218                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7219                      (zero_extend:TI
7220                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7221             (const_int 64))))
7222    (clobber (match_scratch:DI 3 "=1"))
7223    (clobber (reg:CC FLAGS_REG))]
7224   "TARGET_64BIT
7225    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7226   "mul{q}\t%2"
7227   [(set_attr "type" "imul")
7228    (set_attr "length_immediate" "0")
7229    (set (attr "athlon_decode")
7230      (if_then_else (eq_attr "cpu" "athlon")
7231         (const_string "vector")
7232         (const_string "double")))
7233    (set_attr "mode" "DI")])
7235 (define_expand "umulsi3_highpart"
7236   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7237                    (truncate:SI
7238                      (lshiftrt:DI
7239                        (mult:DI (zero_extend:DI
7240                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7241                                 (zero_extend:DI
7242                                   (match_operand:SI 2 "register_operand" "")))
7243                        (const_int 32))))
7244               (clobber (match_scratch:SI 3 ""))
7245               (clobber (reg:CC FLAGS_REG))])]
7246   ""
7247   "")
7249 (define_insn "*umulsi3_highpart_insn"
7250   [(set (match_operand:SI 0 "register_operand" "=d")
7251         (truncate:SI
7252           (lshiftrt:DI
7253             (mult:DI (zero_extend:DI
7254                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7255                      (zero_extend:DI
7256                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7257             (const_int 32))))
7258    (clobber (match_scratch:SI 3 "=1"))
7259    (clobber (reg:CC FLAGS_REG))]
7260   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7261   "mul{l}\t%2"
7262   [(set_attr "type" "imul")
7263    (set_attr "length_immediate" "0")
7264    (set (attr "athlon_decode")
7265      (if_then_else (eq_attr "cpu" "athlon")
7266         (const_string "vector")
7267         (const_string "double")))
7268    (set_attr "mode" "SI")])
7270 (define_insn "*umulsi3_highpart_zext"
7271   [(set (match_operand:DI 0 "register_operand" "=d")
7272         (zero_extend:DI (truncate:SI
7273           (lshiftrt:DI
7274             (mult:DI (zero_extend:DI
7275                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7276                      (zero_extend:DI
7277                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7278             (const_int 32)))))
7279    (clobber (match_scratch:SI 3 "=1"))
7280    (clobber (reg:CC FLAGS_REG))]
7281   "TARGET_64BIT
7282    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7283   "mul{l}\t%2"
7284   [(set_attr "type" "imul")
7285    (set_attr "length_immediate" "0")
7286    (set (attr "athlon_decode")
7287      (if_then_else (eq_attr "cpu" "athlon")
7288         (const_string "vector")
7289         (const_string "double")))
7290    (set_attr "mode" "SI")])
7292 (define_expand "smuldi3_highpart"
7293   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7294                    (truncate:DI
7295                      (lshiftrt:TI
7296                        (mult:TI (sign_extend:TI
7297                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7298                                 (sign_extend:TI
7299                                   (match_operand:DI 2 "register_operand" "")))
7300                        (const_int 64))))
7301               (clobber (match_scratch:DI 3 ""))
7302               (clobber (reg:CC FLAGS_REG))])]
7303   "TARGET_64BIT"
7304   "")
7306 (define_insn "*smuldi3_highpart_rex64"
7307   [(set (match_operand:DI 0 "register_operand" "=d")
7308         (truncate:DI
7309           (lshiftrt:TI
7310             (mult:TI (sign_extend:TI
7311                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7312                      (sign_extend:TI
7313                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7314             (const_int 64))))
7315    (clobber (match_scratch:DI 3 "=1"))
7316    (clobber (reg:CC FLAGS_REG))]
7317   "TARGET_64BIT
7318    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7319   "imul{q}\t%2"
7320   [(set_attr "type" "imul")
7321    (set (attr "athlon_decode")
7322      (if_then_else (eq_attr "cpu" "athlon")
7323         (const_string "vector")
7324         (const_string "double")))
7325    (set_attr "mode" "DI")])
7327 (define_expand "smulsi3_highpart"
7328   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7329                    (truncate:SI
7330                      (lshiftrt:DI
7331                        (mult:DI (sign_extend:DI
7332                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7333                                 (sign_extend:DI
7334                                   (match_operand:SI 2 "register_operand" "")))
7335                        (const_int 32))))
7336               (clobber (match_scratch:SI 3 ""))
7337               (clobber (reg:CC FLAGS_REG))])]
7338   ""
7339   "")
7341 (define_insn "*smulsi3_highpart_insn"
7342   [(set (match_operand:SI 0 "register_operand" "=d")
7343         (truncate:SI
7344           (lshiftrt:DI
7345             (mult:DI (sign_extend:DI
7346                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7347                      (sign_extend:DI
7348                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7349             (const_int 32))))
7350    (clobber (match_scratch:SI 3 "=1"))
7351    (clobber (reg:CC FLAGS_REG))]
7352   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7353   "imul{l}\t%2"
7354   [(set_attr "type" "imul")
7355    (set (attr "athlon_decode")
7356      (if_then_else (eq_attr "cpu" "athlon")
7357         (const_string "vector")
7358         (const_string "double")))
7359    (set_attr "mode" "SI")])
7361 (define_insn "*smulsi3_highpart_zext"
7362   [(set (match_operand:DI 0 "register_operand" "=d")
7363         (zero_extend:DI (truncate:SI
7364           (lshiftrt:DI
7365             (mult:DI (sign_extend:DI
7366                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7367                      (sign_extend:DI
7368                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7369             (const_int 32)))))
7370    (clobber (match_scratch:SI 3 "=1"))
7371    (clobber (reg:CC FLAGS_REG))]
7372   "TARGET_64BIT
7373    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7374   "imul{l}\t%2"
7375   [(set_attr "type" "imul")
7376    (set (attr "athlon_decode")
7377      (if_then_else (eq_attr "cpu" "athlon")
7378         (const_string "vector")
7379         (const_string "double")))
7380    (set_attr "mode" "SI")])
7382 ;; The patterns that match these are at the end of this file.
7384 (define_expand "mulxf3"
7385   [(set (match_operand:XF 0 "register_operand" "")
7386         (mult:XF (match_operand:XF 1 "register_operand" "")
7387                  (match_operand:XF 2 "register_operand" "")))]
7388   "TARGET_80387"
7389   "")
7391 (define_expand "muldf3"
7392   [(set (match_operand:DF 0 "register_operand" "")
7393         (mult:DF (match_operand:DF 1 "register_operand" "")
7394                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7395   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7396   "")
7398 (define_expand "mulsf3"
7399   [(set (match_operand:SF 0 "register_operand" "")
7400         (mult:SF (match_operand:SF 1 "register_operand" "")
7401                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7402   "TARGET_80387 || TARGET_SSE_MATH"
7403   "")
7405 ;; Divide instructions
7407 (define_insn "divqi3"
7408   [(set (match_operand:QI 0 "register_operand" "=a")
7409         (div:QI (match_operand:HI 1 "register_operand" "0")
7410                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7411    (clobber (reg:CC FLAGS_REG))]
7412   "TARGET_QIMODE_MATH"
7413   "idiv{b}\t%2"
7414   [(set_attr "type" "idiv")
7415    (set_attr "mode" "QI")])
7417 (define_insn "udivqi3"
7418   [(set (match_operand:QI 0 "register_operand" "=a")
7419         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7420                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7421    (clobber (reg:CC FLAGS_REG))]
7422   "TARGET_QIMODE_MATH"
7423   "div{b}\t%2"
7424   [(set_attr "type" "idiv")
7425    (set_attr "mode" "QI")])
7427 ;; The patterns that match these are at the end of this file.
7429 (define_expand "divxf3"
7430   [(set (match_operand:XF 0 "register_operand" "")
7431         (div:XF (match_operand:XF 1 "register_operand" "")
7432                 (match_operand:XF 2 "register_operand" "")))]
7433   "TARGET_80387"
7434   "")
7436 (define_expand "divdf3"
7437   [(set (match_operand:DF 0 "register_operand" "")
7438         (div:DF (match_operand:DF 1 "register_operand" "")
7439                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7440    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7441    "")
7443 (define_expand "divsf3"
7444   [(set (match_operand:SF 0 "register_operand" "")
7445         (div:SF (match_operand:SF 1 "register_operand" "")
7446                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7447   "TARGET_80387 || TARGET_SSE_MATH"
7448   "")
7450 ;; Remainder instructions.
7452 (define_expand "divmoddi4"
7453   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7454                    (div:DI (match_operand:DI 1 "register_operand" "")
7455                            (match_operand:DI 2 "nonimmediate_operand" "")))
7456               (set (match_operand:DI 3 "register_operand" "")
7457                    (mod:DI (match_dup 1) (match_dup 2)))
7458               (clobber (reg:CC FLAGS_REG))])]
7459   "TARGET_64BIT"
7460   "")
7462 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7463 ;; Penalize eax case slightly because it results in worse scheduling
7464 ;; of code.
7465 (define_insn "*divmoddi4_nocltd_rex64"
7466   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7467         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7468                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7469    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7470         (mod:DI (match_dup 2) (match_dup 3)))
7471    (clobber (reg:CC FLAGS_REG))]
7472   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7473   "#"
7474   [(set_attr "type" "multi")])
7476 (define_insn "*divmoddi4_cltd_rex64"
7477   [(set (match_operand:DI 0 "register_operand" "=a")
7478         (div:DI (match_operand:DI 2 "register_operand" "a")
7479                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7480    (set (match_operand:DI 1 "register_operand" "=&d")
7481         (mod:DI (match_dup 2) (match_dup 3)))
7482    (clobber (reg:CC FLAGS_REG))]
7483   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7484   "#"
7485   [(set_attr "type" "multi")])
7487 (define_insn "*divmoddi_noext_rex64"
7488   [(set (match_operand:DI 0 "register_operand" "=a")
7489         (div:DI (match_operand:DI 1 "register_operand" "0")
7490                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7491    (set (match_operand:DI 3 "register_operand" "=d")
7492         (mod:DI (match_dup 1) (match_dup 2)))
7493    (use (match_operand:DI 4 "register_operand" "3"))
7494    (clobber (reg:CC FLAGS_REG))]
7495   "TARGET_64BIT"
7496   "idiv{q}\t%2"
7497   [(set_attr "type" "idiv")
7498    (set_attr "mode" "DI")])
7500 (define_split
7501   [(set (match_operand:DI 0 "register_operand" "")
7502         (div:DI (match_operand:DI 1 "register_operand" "")
7503                 (match_operand:DI 2 "nonimmediate_operand" "")))
7504    (set (match_operand:DI 3 "register_operand" "")
7505         (mod:DI (match_dup 1) (match_dup 2)))
7506    (clobber (reg:CC FLAGS_REG))]
7507   "TARGET_64BIT && reload_completed"
7508   [(parallel [(set (match_dup 3)
7509                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7510               (clobber (reg:CC FLAGS_REG))])
7511    (parallel [(set (match_dup 0)
7512                    (div:DI (reg:DI 0) (match_dup 2)))
7513               (set (match_dup 3)
7514                    (mod:DI (reg:DI 0) (match_dup 2)))
7515               (use (match_dup 3))
7516               (clobber (reg:CC FLAGS_REG))])]
7518   /* Avoid use of cltd in favor of a mov+shift.  */
7519   if (!TARGET_USE_CLTD && !optimize_size)
7520     {
7521       if (true_regnum (operands[1]))
7522         emit_move_insn (operands[0], operands[1]);
7523       else
7524         emit_move_insn (operands[3], operands[1]);
7525       operands[4] = operands[3];
7526     }
7527   else
7528     {
7529       gcc_assert (!true_regnum (operands[1]));
7530       operands[4] = operands[1];
7531     }
7535 (define_expand "divmodsi4"
7536   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7537                    (div:SI (match_operand:SI 1 "register_operand" "")
7538                            (match_operand:SI 2 "nonimmediate_operand" "")))
7539               (set (match_operand:SI 3 "register_operand" "")
7540                    (mod:SI (match_dup 1) (match_dup 2)))
7541               (clobber (reg:CC FLAGS_REG))])]
7542   ""
7543   "")
7545 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7546 ;; Penalize eax case slightly because it results in worse scheduling
7547 ;; of code.
7548 (define_insn "*divmodsi4_nocltd"
7549   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7550         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7551                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7552    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7553         (mod:SI (match_dup 2) (match_dup 3)))
7554    (clobber (reg:CC FLAGS_REG))]
7555   "!optimize_size && !TARGET_USE_CLTD"
7556   "#"
7557   [(set_attr "type" "multi")])
7559 (define_insn "*divmodsi4_cltd"
7560   [(set (match_operand:SI 0 "register_operand" "=a")
7561         (div:SI (match_operand:SI 2 "register_operand" "a")
7562                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7563    (set (match_operand:SI 1 "register_operand" "=&d")
7564         (mod:SI (match_dup 2) (match_dup 3)))
7565    (clobber (reg:CC FLAGS_REG))]
7566   "optimize_size || TARGET_USE_CLTD"
7567   "#"
7568   [(set_attr "type" "multi")])
7570 (define_insn "*divmodsi_noext"
7571   [(set (match_operand:SI 0 "register_operand" "=a")
7572         (div:SI (match_operand:SI 1 "register_operand" "0")
7573                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7574    (set (match_operand:SI 3 "register_operand" "=d")
7575         (mod:SI (match_dup 1) (match_dup 2)))
7576    (use (match_operand:SI 4 "register_operand" "3"))
7577    (clobber (reg:CC FLAGS_REG))]
7578   ""
7579   "idiv{l}\t%2"
7580   [(set_attr "type" "idiv")
7581    (set_attr "mode" "SI")])
7583 (define_split
7584   [(set (match_operand:SI 0 "register_operand" "")
7585         (div:SI (match_operand:SI 1 "register_operand" "")
7586                 (match_operand:SI 2 "nonimmediate_operand" "")))
7587    (set (match_operand:SI 3 "register_operand" "")
7588         (mod:SI (match_dup 1) (match_dup 2)))
7589    (clobber (reg:CC FLAGS_REG))]
7590   "reload_completed"
7591   [(parallel [(set (match_dup 3)
7592                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7593               (clobber (reg:CC FLAGS_REG))])
7594    (parallel [(set (match_dup 0)
7595                    (div:SI (reg:SI 0) (match_dup 2)))
7596               (set (match_dup 3)
7597                    (mod:SI (reg:SI 0) (match_dup 2)))
7598               (use (match_dup 3))
7599               (clobber (reg:CC FLAGS_REG))])]
7601   /* Avoid use of cltd in favor of a mov+shift.  */
7602   if (!TARGET_USE_CLTD && !optimize_size)
7603     {
7604       if (true_regnum (operands[1]))
7605         emit_move_insn (operands[0], operands[1]);
7606       else
7607         emit_move_insn (operands[3], operands[1]);
7608       operands[4] = operands[3];
7609     }
7610   else
7611     {
7612       gcc_assert (!true_regnum (operands[1]));
7613       operands[4] = operands[1];
7614     }
7616 ;; %%% Split me.
7617 (define_insn "divmodhi4"
7618   [(set (match_operand:HI 0 "register_operand" "=a")
7619         (div:HI (match_operand:HI 1 "register_operand" "0")
7620                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7621    (set (match_operand:HI 3 "register_operand" "=&d")
7622         (mod:HI (match_dup 1) (match_dup 2)))
7623    (clobber (reg:CC FLAGS_REG))]
7624   "TARGET_HIMODE_MATH"
7625   "cwtd\;idiv{w}\t%2"
7626   [(set_attr "type" "multi")
7627    (set_attr "length_immediate" "0")
7628    (set_attr "mode" "SI")])
7630 (define_insn "udivmoddi4"
7631   [(set (match_operand:DI 0 "register_operand" "=a")
7632         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7633                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7634    (set (match_operand:DI 3 "register_operand" "=&d")
7635         (umod:DI (match_dup 1) (match_dup 2)))
7636    (clobber (reg:CC FLAGS_REG))]
7637   "TARGET_64BIT"
7638   "xor{q}\t%3, %3\;div{q}\t%2"
7639   [(set_attr "type" "multi")
7640    (set_attr "length_immediate" "0")
7641    (set_attr "mode" "DI")])
7643 (define_insn "*udivmoddi4_noext"
7644   [(set (match_operand:DI 0 "register_operand" "=a")
7645         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7646                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7647    (set (match_operand:DI 3 "register_operand" "=d")
7648         (umod:DI (match_dup 1) (match_dup 2)))
7649    (use (match_dup 3))
7650    (clobber (reg:CC FLAGS_REG))]
7651   "TARGET_64BIT"
7652   "div{q}\t%2"
7653   [(set_attr "type" "idiv")
7654    (set_attr "mode" "DI")])
7656 (define_split
7657   [(set (match_operand:DI 0 "register_operand" "")
7658         (udiv:DI (match_operand:DI 1 "register_operand" "")
7659                  (match_operand:DI 2 "nonimmediate_operand" "")))
7660    (set (match_operand:DI 3 "register_operand" "")
7661         (umod:DI (match_dup 1) (match_dup 2)))
7662    (clobber (reg:CC FLAGS_REG))]
7663   "TARGET_64BIT && reload_completed"
7664   [(set (match_dup 3) (const_int 0))
7665    (parallel [(set (match_dup 0)
7666                    (udiv:DI (match_dup 1) (match_dup 2)))
7667               (set (match_dup 3)
7668                    (umod:DI (match_dup 1) (match_dup 2)))
7669               (use (match_dup 3))
7670               (clobber (reg:CC FLAGS_REG))])]
7671   "")
7673 (define_insn "udivmodsi4"
7674   [(set (match_operand:SI 0 "register_operand" "=a")
7675         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7676                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7677    (set (match_operand:SI 3 "register_operand" "=&d")
7678         (umod:SI (match_dup 1) (match_dup 2)))
7679    (clobber (reg:CC FLAGS_REG))]
7680   ""
7681   "xor{l}\t%3, %3\;div{l}\t%2"
7682   [(set_attr "type" "multi")
7683    (set_attr "length_immediate" "0")
7684    (set_attr "mode" "SI")])
7686 (define_insn "*udivmodsi4_noext"
7687   [(set (match_operand:SI 0 "register_operand" "=a")
7688         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7689                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7690    (set (match_operand:SI 3 "register_operand" "=d")
7691         (umod:SI (match_dup 1) (match_dup 2)))
7692    (use (match_dup 3))
7693    (clobber (reg:CC FLAGS_REG))]
7694   ""
7695   "div{l}\t%2"
7696   [(set_attr "type" "idiv")
7697    (set_attr "mode" "SI")])
7699 (define_split
7700   [(set (match_operand:SI 0 "register_operand" "")
7701         (udiv:SI (match_operand:SI 1 "register_operand" "")
7702                  (match_operand:SI 2 "nonimmediate_operand" "")))
7703    (set (match_operand:SI 3 "register_operand" "")
7704         (umod:SI (match_dup 1) (match_dup 2)))
7705    (clobber (reg:CC FLAGS_REG))]
7706   "reload_completed"
7707   [(set (match_dup 3) (const_int 0))
7708    (parallel [(set (match_dup 0)
7709                    (udiv:SI (match_dup 1) (match_dup 2)))
7710               (set (match_dup 3)
7711                    (umod:SI (match_dup 1) (match_dup 2)))
7712               (use (match_dup 3))
7713               (clobber (reg:CC FLAGS_REG))])]
7714   "")
7716 (define_expand "udivmodhi4"
7717   [(set (match_dup 4) (const_int 0))
7718    (parallel [(set (match_operand:HI 0 "register_operand" "")
7719                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7720                             (match_operand:HI 2 "nonimmediate_operand" "")))
7721               (set (match_operand:HI 3 "register_operand" "")
7722                    (umod:HI (match_dup 1) (match_dup 2)))
7723               (use (match_dup 4))
7724               (clobber (reg:CC FLAGS_REG))])]
7725   "TARGET_HIMODE_MATH"
7726   "operands[4] = gen_reg_rtx (HImode);")
7728 (define_insn "*udivmodhi_noext"
7729   [(set (match_operand:HI 0 "register_operand" "=a")
7730         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7731                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7732    (set (match_operand:HI 3 "register_operand" "=d")
7733         (umod:HI (match_dup 1) (match_dup 2)))
7734    (use (match_operand:HI 4 "register_operand" "3"))
7735    (clobber (reg:CC FLAGS_REG))]
7736   ""
7737   "div{w}\t%2"
7738   [(set_attr "type" "idiv")
7739    (set_attr "mode" "HI")])
7741 ;; We cannot use div/idiv for double division, because it causes
7742 ;; "division by zero" on the overflow and that's not what we expect
7743 ;; from truncate.  Because true (non truncating) double division is
7744 ;; never generated, we can't create this insn anyway.
7746 ;(define_insn ""
7747 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7748 ;       (truncate:SI
7749 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7750 ;                  (zero_extend:DI
7751 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7752 ;   (set (match_operand:SI 3 "register_operand" "=d")
7753 ;       (truncate:SI
7754 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7755 ;   (clobber (reg:CC FLAGS_REG))]
7756 ;  ""
7757 ;  "div{l}\t{%2, %0|%0, %2}"
7758 ;  [(set_attr "type" "idiv")])
7760 ;;- Logical AND instructions
7762 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7763 ;; Note that this excludes ah.
7765 (define_insn "*testdi_1_rex64"
7766   [(set (reg FLAGS_REG)
7767         (compare
7768           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7769                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7770           (const_int 0)))]
7771   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7772    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7773   "@
7774    test{l}\t{%k1, %k0|%k0, %k1}
7775    test{l}\t{%k1, %k0|%k0, %k1}
7776    test{q}\t{%1, %0|%0, %1}
7777    test{q}\t{%1, %0|%0, %1}
7778    test{q}\t{%1, %0|%0, %1}"
7779   [(set_attr "type" "test")
7780    (set_attr "modrm" "0,1,0,1,1")
7781    (set_attr "mode" "SI,SI,DI,DI,DI")
7782    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7784 (define_insn "testsi_1"
7785   [(set (reg FLAGS_REG)
7786         (compare
7787           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7788                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7789           (const_int 0)))]
7790   "ix86_match_ccmode (insn, CCNOmode)
7791    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7792   "test{l}\t{%1, %0|%0, %1}"
7793   [(set_attr "type" "test")
7794    (set_attr "modrm" "0,1,1")
7795    (set_attr "mode" "SI")
7796    (set_attr "pent_pair" "uv,np,uv")])
7798 (define_expand "testsi_ccno_1"
7799   [(set (reg:CCNO FLAGS_REG)
7800         (compare:CCNO
7801           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7802                   (match_operand:SI 1 "nonmemory_operand" ""))
7803           (const_int 0)))]
7804   ""
7805   "")
7807 (define_insn "*testhi_1"
7808   [(set (reg FLAGS_REG)
7809         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7810                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7811                  (const_int 0)))]
7812   "ix86_match_ccmode (insn, CCNOmode)
7813    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7814   "test{w}\t{%1, %0|%0, %1}"
7815   [(set_attr "type" "test")
7816    (set_attr "modrm" "0,1,1")
7817    (set_attr "mode" "HI")
7818    (set_attr "pent_pair" "uv,np,uv")])
7820 (define_expand "testqi_ccz_1"
7821   [(set (reg:CCZ FLAGS_REG)
7822         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7823                              (match_operand:QI 1 "nonmemory_operand" ""))
7824                  (const_int 0)))]
7825   ""
7826   "")
7828 (define_insn "*testqi_1_maybe_si"
7829   [(set (reg FLAGS_REG)
7830         (compare
7831           (and:QI
7832             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7833             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7834           (const_int 0)))]
7835    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7836     && ix86_match_ccmode (insn,
7837                          CONST_INT_P (operands[1])
7838                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7840   if (which_alternative == 3)
7841     {
7842       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7843         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7844       return "test{l}\t{%1, %k0|%k0, %1}";
7845     }
7846   return "test{b}\t{%1, %0|%0, %1}";
7848   [(set_attr "type" "test")
7849    (set_attr "modrm" "0,1,1,1")
7850    (set_attr "mode" "QI,QI,QI,SI")
7851    (set_attr "pent_pair" "uv,np,uv,np")])
7853 (define_insn "*testqi_1"
7854   [(set (reg FLAGS_REG)
7855         (compare
7856           (and:QI
7857             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7858             (match_operand:QI 1 "general_operand" "n,n,qn"))
7859           (const_int 0)))]
7860   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7861    && ix86_match_ccmode (insn, CCNOmode)"
7862   "test{b}\t{%1, %0|%0, %1}"
7863   [(set_attr "type" "test")
7864    (set_attr "modrm" "0,1,1")
7865    (set_attr "mode" "QI")
7866    (set_attr "pent_pair" "uv,np,uv")])
7868 (define_expand "testqi_ext_ccno_0"
7869   [(set (reg:CCNO FLAGS_REG)
7870         (compare:CCNO
7871           (and:SI
7872             (zero_extract:SI
7873               (match_operand 0 "ext_register_operand" "")
7874               (const_int 8)
7875               (const_int 8))
7876             (match_operand 1 "const_int_operand" ""))
7877           (const_int 0)))]
7878   ""
7879   "")
7881 (define_insn "*testqi_ext_0"
7882   [(set (reg FLAGS_REG)
7883         (compare
7884           (and:SI
7885             (zero_extract:SI
7886               (match_operand 0 "ext_register_operand" "Q")
7887               (const_int 8)
7888               (const_int 8))
7889             (match_operand 1 "const_int_operand" "n"))
7890           (const_int 0)))]
7891   "ix86_match_ccmode (insn, CCNOmode)"
7892   "test{b}\t{%1, %h0|%h0, %1}"
7893   [(set_attr "type" "test")
7894    (set_attr "mode" "QI")
7895    (set_attr "length_immediate" "1")
7896    (set_attr "pent_pair" "np")])
7898 (define_insn "*testqi_ext_1"
7899   [(set (reg FLAGS_REG)
7900         (compare
7901           (and:SI
7902             (zero_extract:SI
7903               (match_operand 0 "ext_register_operand" "Q")
7904               (const_int 8)
7905               (const_int 8))
7906             (zero_extend:SI
7907               (match_operand:QI 1 "general_operand" "Qm")))
7908           (const_int 0)))]
7909   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7910    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7911   "test{b}\t{%1, %h0|%h0, %1}"
7912   [(set_attr "type" "test")
7913    (set_attr "mode" "QI")])
7915 (define_insn "*testqi_ext_1_rex64"
7916   [(set (reg FLAGS_REG)
7917         (compare
7918           (and:SI
7919             (zero_extract:SI
7920               (match_operand 0 "ext_register_operand" "Q")
7921               (const_int 8)
7922               (const_int 8))
7923             (zero_extend:SI
7924               (match_operand:QI 1 "register_operand" "Q")))
7925           (const_int 0)))]
7926   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7927   "test{b}\t{%1, %h0|%h0, %1}"
7928   [(set_attr "type" "test")
7929    (set_attr "mode" "QI")])
7931 (define_insn "*testqi_ext_2"
7932   [(set (reg FLAGS_REG)
7933         (compare
7934           (and:SI
7935             (zero_extract:SI
7936               (match_operand 0 "ext_register_operand" "Q")
7937               (const_int 8)
7938               (const_int 8))
7939             (zero_extract:SI
7940               (match_operand 1 "ext_register_operand" "Q")
7941               (const_int 8)
7942               (const_int 8)))
7943           (const_int 0)))]
7944   "ix86_match_ccmode (insn, CCNOmode)"
7945   "test{b}\t{%h1, %h0|%h0, %h1}"
7946   [(set_attr "type" "test")
7947    (set_attr "mode" "QI")])
7949 ;; Combine likes to form bit extractions for some tests.  Humor it.
7950 (define_insn "*testqi_ext_3"
7951   [(set (reg FLAGS_REG)
7952         (compare (zero_extract:SI
7953                    (match_operand 0 "nonimmediate_operand" "rm")
7954                    (match_operand:SI 1 "const_int_operand" "")
7955                    (match_operand:SI 2 "const_int_operand" ""))
7956                  (const_int 0)))]
7957   "ix86_match_ccmode (insn, CCNOmode)
7958    && INTVAL (operands[1]) > 0
7959    && INTVAL (operands[2]) >= 0
7960    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7961    && (GET_MODE (operands[0]) == SImode
7962        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7963        || GET_MODE (operands[0]) == HImode
7964        || GET_MODE (operands[0]) == QImode)"
7965   "#")
7967 (define_insn "*testqi_ext_3_rex64"
7968   [(set (reg FLAGS_REG)
7969         (compare (zero_extract:DI
7970                    (match_operand 0 "nonimmediate_operand" "rm")
7971                    (match_operand:DI 1 "const_int_operand" "")
7972                    (match_operand:DI 2 "const_int_operand" ""))
7973                  (const_int 0)))]
7974   "TARGET_64BIT
7975    && ix86_match_ccmode (insn, CCNOmode)
7976    && INTVAL (operands[1]) > 0
7977    && INTVAL (operands[2]) >= 0
7978    /* Ensure that resulting mask is zero or sign extended operand.  */
7979    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7980        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7981            && INTVAL (operands[1]) > 32))
7982    && (GET_MODE (operands[0]) == SImode
7983        || GET_MODE (operands[0]) == DImode
7984        || GET_MODE (operands[0]) == HImode
7985        || GET_MODE (operands[0]) == QImode)"
7986   "#")
7988 (define_split
7989   [(set (match_operand 0 "flags_reg_operand" "")
7990         (match_operator 1 "compare_operator"
7991           [(zero_extract
7992              (match_operand 2 "nonimmediate_operand" "")
7993              (match_operand 3 "const_int_operand" "")
7994              (match_operand 4 "const_int_operand" ""))
7995            (const_int 0)]))]
7996   "ix86_match_ccmode (insn, CCNOmode)"
7997   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7999   rtx val = operands[2];
8000   HOST_WIDE_INT len = INTVAL (operands[3]);
8001   HOST_WIDE_INT pos = INTVAL (operands[4]);
8002   HOST_WIDE_INT mask;
8003   enum machine_mode mode, submode;
8005   mode = GET_MODE (val);
8006   if (MEM_P (val))
8007     {
8008       /* ??? Combine likes to put non-volatile mem extractions in QImode
8009          no matter the size of the test.  So find a mode that works.  */
8010       if (! MEM_VOLATILE_P (val))
8011         {
8012           mode = smallest_mode_for_size (pos + len, MODE_INT);
8013           val = adjust_address (val, mode, 0);
8014         }
8015     }
8016   else if (GET_CODE (val) == SUBREG
8017            && (submode = GET_MODE (SUBREG_REG (val)),
8018                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8019            && pos + len <= GET_MODE_BITSIZE (submode))
8020     {
8021       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8022       mode = submode;
8023       val = SUBREG_REG (val);
8024     }
8025   else if (mode == HImode && pos + len <= 8)
8026     {
8027       /* Small HImode tests can be converted to QImode.  */
8028       mode = QImode;
8029       val = gen_lowpart (QImode, val);
8030     }
8032   if (len == HOST_BITS_PER_WIDE_INT)
8033     mask = -1;
8034   else
8035     mask = ((HOST_WIDE_INT)1 << len) - 1;
8036   mask <<= pos;
8038   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8041 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8042 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8043 ;; this is relatively important trick.
8044 ;; Do the conversion only post-reload to avoid limiting of the register class
8045 ;; to QI regs.
8046 (define_split
8047   [(set (match_operand 0 "flags_reg_operand" "")
8048         (match_operator 1 "compare_operator"
8049           [(and (match_operand 2 "register_operand" "")
8050                 (match_operand 3 "const_int_operand" ""))
8051            (const_int 0)]))]
8052    "reload_completed
8053     && QI_REG_P (operands[2])
8054     && GET_MODE (operands[2]) != QImode
8055     && ((ix86_match_ccmode (insn, CCZmode)
8056          && !(INTVAL (operands[3]) & ~(255 << 8)))
8057         || (ix86_match_ccmode (insn, CCNOmode)
8058             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8059   [(set (match_dup 0)
8060         (match_op_dup 1
8061           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8062                    (match_dup 3))
8063            (const_int 0)]))]
8064   "operands[2] = gen_lowpart (SImode, operands[2]);
8065    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8067 (define_split
8068   [(set (match_operand 0 "flags_reg_operand" "")
8069         (match_operator 1 "compare_operator"
8070           [(and (match_operand 2 "nonimmediate_operand" "")
8071                 (match_operand 3 "const_int_operand" ""))
8072            (const_int 0)]))]
8073    "reload_completed
8074     && GET_MODE (operands[2]) != QImode
8075     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8076     && ((ix86_match_ccmode (insn, CCZmode)
8077          && !(INTVAL (operands[3]) & ~255))
8078         || (ix86_match_ccmode (insn, CCNOmode)
8079             && !(INTVAL (operands[3]) & ~127)))"
8080   [(set (match_dup 0)
8081         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8082                          (const_int 0)]))]
8083   "operands[2] = gen_lowpart (QImode, operands[2]);
8084    operands[3] = gen_lowpart (QImode, operands[3]);")
8087 ;; %%% This used to optimize known byte-wide and operations to memory,
8088 ;; and sometimes to QImode registers.  If this is considered useful,
8089 ;; it should be done with splitters.
8091 (define_expand "anddi3"
8092   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8093         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8094                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8095    (clobber (reg:CC FLAGS_REG))]
8096   "TARGET_64BIT"
8097   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8099 (define_insn "*anddi_1_rex64"
8100   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8101         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8102                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8103    (clobber (reg:CC FLAGS_REG))]
8104   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8106   switch (get_attr_type (insn))
8107     {
8108     case TYPE_IMOVX:
8109       {
8110         enum machine_mode mode;
8112         gcc_assert (CONST_INT_P (operands[2]));
8113         if (INTVAL (operands[2]) == 0xff)
8114           mode = QImode;
8115         else
8116           {
8117             gcc_assert (INTVAL (operands[2]) == 0xffff);
8118             mode = HImode;
8119           }
8121         operands[1] = gen_lowpart (mode, operands[1]);
8122         if (mode == QImode)
8123           return "movz{bq|x}\t{%1,%0|%0, %1}";
8124         else
8125           return "movz{wq|x}\t{%1,%0|%0, %1}";
8126       }
8128     default:
8129       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8130       if (get_attr_mode (insn) == MODE_SI)
8131         return "and{l}\t{%k2, %k0|%k0, %k2}";
8132       else
8133         return "and{q}\t{%2, %0|%0, %2}";
8134     }
8136   [(set_attr "type" "alu,alu,alu,imovx")
8137    (set_attr "length_immediate" "*,*,*,0")
8138    (set_attr "mode" "SI,DI,DI,DI")])
8140 (define_insn "*anddi_2"
8141   [(set (reg FLAGS_REG)
8142         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8143                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8144                  (const_int 0)))
8145    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8146         (and:DI (match_dup 1) (match_dup 2)))]
8147   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8148    && ix86_binary_operator_ok (AND, DImode, operands)"
8149   "@
8150    and{l}\t{%k2, %k0|%k0, %k2}
8151    and{q}\t{%2, %0|%0, %2}
8152    and{q}\t{%2, %0|%0, %2}"
8153   [(set_attr "type" "alu")
8154    (set_attr "mode" "SI,DI,DI")])
8156 (define_expand "andsi3"
8157   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8158         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8159                 (match_operand:SI 2 "general_operand" "")))
8160    (clobber (reg:CC FLAGS_REG))]
8161   ""
8162   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8164 (define_insn "*andsi_1"
8165   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8166         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8167                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8168    (clobber (reg:CC FLAGS_REG))]
8169   "ix86_binary_operator_ok (AND, SImode, operands)"
8171   switch (get_attr_type (insn))
8172     {
8173     case TYPE_IMOVX:
8174       {
8175         enum machine_mode mode;
8177         gcc_assert (CONST_INT_P (operands[2]));
8178         if (INTVAL (operands[2]) == 0xff)
8179           mode = QImode;
8180         else
8181           {
8182             gcc_assert (INTVAL (operands[2]) == 0xffff);
8183             mode = HImode;
8184           }
8186         operands[1] = gen_lowpart (mode, operands[1]);
8187         if (mode == QImode)
8188           return "movz{bl|x}\t{%1,%0|%0, %1}";
8189         else
8190           return "movz{wl|x}\t{%1,%0|%0, %1}";
8191       }
8193     default:
8194       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8195       return "and{l}\t{%2, %0|%0, %2}";
8196     }
8198   [(set_attr "type" "alu,alu,imovx")
8199    (set_attr "length_immediate" "*,*,0")
8200    (set_attr "mode" "SI")])
8202 (define_split
8203   [(set (match_operand 0 "register_operand" "")
8204         (and (match_dup 0)
8205              (const_int -65536)))
8206    (clobber (reg:CC FLAGS_REG))]
8207   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8208   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8209   "operands[1] = gen_lowpart (HImode, operands[0]);")
8211 (define_split
8212   [(set (match_operand 0 "ext_register_operand" "")
8213         (and (match_dup 0)
8214              (const_int -256)))
8215    (clobber (reg:CC FLAGS_REG))]
8216   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8217   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8218   "operands[1] = gen_lowpart (QImode, operands[0]);")
8220 (define_split
8221   [(set (match_operand 0 "ext_register_operand" "")
8222         (and (match_dup 0)
8223              (const_int -65281)))
8224    (clobber (reg:CC FLAGS_REG))]
8225   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8226   [(parallel [(set (zero_extract:SI (match_dup 0)
8227                                     (const_int 8)
8228                                     (const_int 8))
8229                    (xor:SI
8230                      (zero_extract:SI (match_dup 0)
8231                                       (const_int 8)
8232                                       (const_int 8))
8233                      (zero_extract:SI (match_dup 0)
8234                                       (const_int 8)
8235                                       (const_int 8))))
8236               (clobber (reg:CC FLAGS_REG))])]
8237   "operands[0] = gen_lowpart (SImode, operands[0]);")
8239 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8240 (define_insn "*andsi_1_zext"
8241   [(set (match_operand:DI 0 "register_operand" "=r")
8242         (zero_extend:DI
8243           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8244                   (match_operand:SI 2 "general_operand" "rim"))))
8245    (clobber (reg:CC FLAGS_REG))]
8246   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8247   "and{l}\t{%2, %k0|%k0, %2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "SI")])
8251 (define_insn "*andsi_2"
8252   [(set (reg FLAGS_REG)
8253         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8254                          (match_operand:SI 2 "general_operand" "rim,ri"))
8255                  (const_int 0)))
8256    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8257         (and:SI (match_dup 1) (match_dup 2)))]
8258   "ix86_match_ccmode (insn, CCNOmode)
8259    && ix86_binary_operator_ok (AND, SImode, operands)"
8260   "and{l}\t{%2, %0|%0, %2}"
8261   [(set_attr "type" "alu")
8262    (set_attr "mode" "SI")])
8264 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8265 (define_insn "*andsi_2_zext"
8266   [(set (reg FLAGS_REG)
8267         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8268                          (match_operand:SI 2 "general_operand" "rim"))
8269                  (const_int 0)))
8270    (set (match_operand:DI 0 "register_operand" "=r")
8271         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8272   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8273    && ix86_binary_operator_ok (AND, SImode, operands)"
8274   "and{l}\t{%2, %k0|%k0, %2}"
8275   [(set_attr "type" "alu")
8276    (set_attr "mode" "SI")])
8278 (define_expand "andhi3"
8279   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8280         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8281                 (match_operand:HI 2 "general_operand" "")))
8282    (clobber (reg:CC FLAGS_REG))]
8283   "TARGET_HIMODE_MATH"
8284   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8286 (define_insn "*andhi_1"
8287   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8288         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8289                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8290    (clobber (reg:CC FLAGS_REG))]
8291   "ix86_binary_operator_ok (AND, HImode, operands)"
8293   switch (get_attr_type (insn))
8294     {
8295     case TYPE_IMOVX:
8296       gcc_assert (CONST_INT_P (operands[2]));
8297       gcc_assert (INTVAL (operands[2]) == 0xff);
8298       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8300     default:
8301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8303       return "and{w}\t{%2, %0|%0, %2}";
8304     }
8306   [(set_attr "type" "alu,alu,imovx")
8307    (set_attr "length_immediate" "*,*,0")
8308    (set_attr "mode" "HI,HI,SI")])
8310 (define_insn "*andhi_2"
8311   [(set (reg FLAGS_REG)
8312         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8313                          (match_operand:HI 2 "general_operand" "rim,ri"))
8314                  (const_int 0)))
8315    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8316         (and:HI (match_dup 1) (match_dup 2)))]
8317   "ix86_match_ccmode (insn, CCNOmode)
8318    && ix86_binary_operator_ok (AND, HImode, operands)"
8319   "and{w}\t{%2, %0|%0, %2}"
8320   [(set_attr "type" "alu")
8321    (set_attr "mode" "HI")])
8323 (define_expand "andqi3"
8324   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8325         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8326                 (match_operand:QI 2 "general_operand" "")))
8327    (clobber (reg:CC FLAGS_REG))]
8328   "TARGET_QIMODE_MATH"
8329   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8331 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8332 (define_insn "*andqi_1"
8333   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8334         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8335                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8336    (clobber (reg:CC FLAGS_REG))]
8337   "ix86_binary_operator_ok (AND, QImode, operands)"
8338   "@
8339    and{b}\t{%2, %0|%0, %2}
8340    and{b}\t{%2, %0|%0, %2}
8341    and{l}\t{%k2, %k0|%k0, %k2}"
8342   [(set_attr "type" "alu")
8343    (set_attr "mode" "QI,QI,SI")])
8345 (define_insn "*andqi_1_slp"
8346   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8347         (and:QI (match_dup 0)
8348                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8349    (clobber (reg:CC FLAGS_REG))]
8350   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8351    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8352   "and{b}\t{%1, %0|%0, %1}"
8353   [(set_attr "type" "alu1")
8354    (set_attr "mode" "QI")])
8356 (define_insn "*andqi_2_maybe_si"
8357   [(set (reg FLAGS_REG)
8358         (compare (and:QI
8359                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8360                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8361                  (const_int 0)))
8362    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8363         (and:QI (match_dup 1) (match_dup 2)))]
8364   "ix86_binary_operator_ok (AND, QImode, operands)
8365    && ix86_match_ccmode (insn,
8366                          CONST_INT_P (operands[2])
8367                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8369   if (which_alternative == 2)
8370     {
8371       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8372         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8373       return "and{l}\t{%2, %k0|%k0, %2}";
8374     }
8375   return "and{b}\t{%2, %0|%0, %2}";
8377   [(set_attr "type" "alu")
8378    (set_attr "mode" "QI,QI,SI")])
8380 (define_insn "*andqi_2"
8381   [(set (reg FLAGS_REG)
8382         (compare (and:QI
8383                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8384                    (match_operand:QI 2 "general_operand" "qim,qi"))
8385                  (const_int 0)))
8386    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8387         (and:QI (match_dup 1) (match_dup 2)))]
8388   "ix86_match_ccmode (insn, CCNOmode)
8389    && ix86_binary_operator_ok (AND, QImode, operands)"
8390   "and{b}\t{%2, %0|%0, %2}"
8391   [(set_attr "type" "alu")
8392    (set_attr "mode" "QI")])
8394 (define_insn "*andqi_2_slp"
8395   [(set (reg FLAGS_REG)
8396         (compare (and:QI
8397                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8398                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8399                  (const_int 0)))
8400    (set (strict_low_part (match_dup 0))
8401         (and:QI (match_dup 0) (match_dup 1)))]
8402   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8403    && ix86_match_ccmode (insn, CCNOmode)
8404    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8405   "and{b}\t{%1, %0|%0, %1}"
8406   [(set_attr "type" "alu1")
8407    (set_attr "mode" "QI")])
8409 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8410 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8411 ;; for a QImode operand, which of course failed.
8413 (define_insn "andqi_ext_0"
8414   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8415                          (const_int 8)
8416                          (const_int 8))
8417         (and:SI
8418           (zero_extract:SI
8419             (match_operand 1 "ext_register_operand" "0")
8420             (const_int 8)
8421             (const_int 8))
8422           (match_operand 2 "const_int_operand" "n")))
8423    (clobber (reg:CC FLAGS_REG))]
8424   ""
8425   "and{b}\t{%2, %h0|%h0, %2}"
8426   [(set_attr "type" "alu")
8427    (set_attr "length_immediate" "1")
8428    (set_attr "mode" "QI")])
8430 ;; Generated by peephole translating test to and.  This shows up
8431 ;; often in fp comparisons.
8433 (define_insn "*andqi_ext_0_cc"
8434   [(set (reg FLAGS_REG)
8435         (compare
8436           (and:SI
8437             (zero_extract:SI
8438               (match_operand 1 "ext_register_operand" "0")
8439               (const_int 8)
8440               (const_int 8))
8441             (match_operand 2 "const_int_operand" "n"))
8442           (const_int 0)))
8443    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444                          (const_int 8)
8445                          (const_int 8))
8446         (and:SI
8447           (zero_extract:SI
8448             (match_dup 1)
8449             (const_int 8)
8450             (const_int 8))
8451           (match_dup 2)))]
8452   "ix86_match_ccmode (insn, CCNOmode)"
8453   "and{b}\t{%2, %h0|%h0, %2}"
8454   [(set_attr "type" "alu")
8455    (set_attr "length_immediate" "1")
8456    (set_attr "mode" "QI")])
8458 (define_insn "*andqi_ext_1"
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:QI 2 "general_operand" "Qm"))))
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_1_rex64"
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_extend:SI
8486             (match_operand 2 "ext_register_operand" "Q"))))
8487    (clobber (reg:CC FLAGS_REG))]
8488   "TARGET_64BIT"
8489   "and{b}\t{%2, %h0|%h0, %2}"
8490   [(set_attr "type" "alu")
8491    (set_attr "length_immediate" "0")
8492    (set_attr "mode" "QI")])
8494 (define_insn "*andqi_ext_2"
8495   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8496                          (const_int 8)
8497                          (const_int 8))
8498         (and:SI
8499           (zero_extract:SI
8500             (match_operand 1 "ext_register_operand" "%0")
8501             (const_int 8)
8502             (const_int 8))
8503           (zero_extract:SI
8504             (match_operand 2 "ext_register_operand" "Q")
8505             (const_int 8)
8506             (const_int 8))))
8507    (clobber (reg:CC FLAGS_REG))]
8508   ""
8509   "and{b}\t{%h2, %h0|%h0, %h2}"
8510   [(set_attr "type" "alu")
8511    (set_attr "length_immediate" "0")
8512    (set_attr "mode" "QI")])
8514 ;; Convert wide AND instructions with immediate operand to shorter QImode
8515 ;; equivalents when possible.
8516 ;; Don't do the splitting with memory operands, since it introduces risk
8517 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8518 ;; for size, but that can (should?) be handled by generic code instead.
8519 (define_split
8520   [(set (match_operand 0 "register_operand" "")
8521         (and (match_operand 1 "register_operand" "")
8522              (match_operand 2 "const_int_operand" "")))
8523    (clobber (reg:CC FLAGS_REG))]
8524    "reload_completed
8525     && QI_REG_P (operands[0])
8526     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8527     && !(~INTVAL (operands[2]) & ~(255 << 8))
8528     && GET_MODE (operands[0]) != QImode"
8529   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8530                    (and:SI (zero_extract:SI (match_dup 1)
8531                                             (const_int 8) (const_int 8))
8532                            (match_dup 2)))
8533               (clobber (reg:CC FLAGS_REG))])]
8534   "operands[0] = gen_lowpart (SImode, operands[0]);
8535    operands[1] = gen_lowpart (SImode, operands[1]);
8536    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8538 ;; Since AND can be encoded with sign extended immediate, this is only
8539 ;; profitable when 7th bit is not set.
8540 (define_split
8541   [(set (match_operand 0 "register_operand" "")
8542         (and (match_operand 1 "general_operand" "")
8543              (match_operand 2 "const_int_operand" "")))
8544    (clobber (reg:CC FLAGS_REG))]
8545    "reload_completed
8546     && ANY_QI_REG_P (operands[0])
8547     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8548     && !(~INTVAL (operands[2]) & ~255)
8549     && !(INTVAL (operands[2]) & 128)
8550     && GET_MODE (operands[0]) != QImode"
8551   [(parallel [(set (strict_low_part (match_dup 0))
8552                    (and:QI (match_dup 1)
8553                            (match_dup 2)))
8554               (clobber (reg:CC FLAGS_REG))])]
8555   "operands[0] = gen_lowpart (QImode, operands[0]);
8556    operands[1] = gen_lowpart (QImode, operands[1]);
8557    operands[2] = gen_lowpart (QImode, operands[2]);")
8559 ;; Logical inclusive OR instructions
8561 ;; %%% This used to optimize known byte-wide and operations to memory.
8562 ;; If this is considered useful, it should be done with splitters.
8564 (define_expand "iordi3"
8565   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8566         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8567                 (match_operand:DI 2 "x86_64_general_operand" "")))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "TARGET_64BIT"
8570   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8572 (define_insn "*iordi_1_rex64"
8573   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8574         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8575                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8576    (clobber (reg:CC FLAGS_REG))]
8577   "TARGET_64BIT
8578    && ix86_binary_operator_ok (IOR, DImode, operands)"
8579   "or{q}\t{%2, %0|%0, %2}"
8580   [(set_attr "type" "alu")
8581    (set_attr "mode" "DI")])
8583 (define_insn "*iordi_2_rex64"
8584   [(set (reg FLAGS_REG)
8585         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8586                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8587                  (const_int 0)))
8588    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8589         (ior:DI (match_dup 1) (match_dup 2)))]
8590   "TARGET_64BIT
8591    && ix86_match_ccmode (insn, CCNOmode)
8592    && ix86_binary_operator_ok (IOR, DImode, operands)"
8593   "or{q}\t{%2, %0|%0, %2}"
8594   [(set_attr "type" "alu")
8595    (set_attr "mode" "DI")])
8597 (define_insn "*iordi_3_rex64"
8598   [(set (reg FLAGS_REG)
8599         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8600                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8601                  (const_int 0)))
8602    (clobber (match_scratch:DI 0 "=r"))]
8603   "TARGET_64BIT
8604    && ix86_match_ccmode (insn, CCNOmode)
8605    && ix86_binary_operator_ok (IOR, DImode, operands)"
8606   "or{q}\t{%2, %0|%0, %2}"
8607   [(set_attr "type" "alu")
8608    (set_attr "mode" "DI")])
8611 (define_expand "iorsi3"
8612   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8613         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8614                 (match_operand:SI 2 "general_operand" "")))
8615    (clobber (reg:CC FLAGS_REG))]
8616   ""
8617   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8619 (define_insn "*iorsi_1"
8620   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8621         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8622                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8623    (clobber (reg:CC FLAGS_REG))]
8624   "ix86_binary_operator_ok (IOR, SImode, operands)"
8625   "or{l}\t{%2, %0|%0, %2}"
8626   [(set_attr "type" "alu")
8627    (set_attr "mode" "SI")])
8629 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8630 (define_insn "*iorsi_1_zext"
8631   [(set (match_operand:DI 0 "register_operand" "=rm")
8632         (zero_extend:DI
8633           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8634                   (match_operand:SI 2 "general_operand" "rim"))))
8635    (clobber (reg:CC FLAGS_REG))]
8636   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8637   "or{l}\t{%2, %k0|%k0, %2}"
8638   [(set_attr "type" "alu")
8639    (set_attr "mode" "SI")])
8641 (define_insn "*iorsi_1_zext_imm"
8642   [(set (match_operand:DI 0 "register_operand" "=rm")
8643         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8644                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8645    (clobber (reg:CC FLAGS_REG))]
8646   "TARGET_64BIT"
8647   "or{l}\t{%2, %k0|%k0, %2}"
8648   [(set_attr "type" "alu")
8649    (set_attr "mode" "SI")])
8651 (define_insn "*iorsi_2"
8652   [(set (reg FLAGS_REG)
8653         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8654                          (match_operand:SI 2 "general_operand" "rim,ri"))
8655                  (const_int 0)))
8656    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8657         (ior:SI (match_dup 1) (match_dup 2)))]
8658   "ix86_match_ccmode (insn, CCNOmode)
8659    && ix86_binary_operator_ok (IOR, SImode, operands)"
8660   "or{l}\t{%2, %0|%0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "mode" "SI")])
8664 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8665 ;; ??? Special case for immediate operand is missing - it is tricky.
8666 (define_insn "*iorsi_2_zext"
8667   [(set (reg FLAGS_REG)
8668         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8669                          (match_operand:SI 2 "general_operand" "rim"))
8670                  (const_int 0)))
8671    (set (match_operand:DI 0 "register_operand" "=r")
8672         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8673   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8674    && ix86_binary_operator_ok (IOR, SImode, operands)"
8675   "or{l}\t{%2, %k0|%k0, %2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "mode" "SI")])
8679 (define_insn "*iorsi_2_zext_imm"
8680   [(set (reg FLAGS_REG)
8681         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8682                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8683                  (const_int 0)))
8684    (set (match_operand:DI 0 "register_operand" "=r")
8685         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8686   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8687    && ix86_binary_operator_ok (IOR, SImode, operands)"
8688   "or{l}\t{%2, %k0|%k0, %2}"
8689   [(set_attr "type" "alu")
8690    (set_attr "mode" "SI")])
8692 (define_insn "*iorsi_3"
8693   [(set (reg FLAGS_REG)
8694         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8695                          (match_operand:SI 2 "general_operand" "rim"))
8696                  (const_int 0)))
8697    (clobber (match_scratch:SI 0 "=r"))]
8698   "ix86_match_ccmode (insn, CCNOmode)
8699    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8700   "or{l}\t{%2, %0|%0, %2}"
8701   [(set_attr "type" "alu")
8702    (set_attr "mode" "SI")])
8704 (define_expand "iorhi3"
8705   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8706         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8707                 (match_operand:HI 2 "general_operand" "")))
8708    (clobber (reg:CC FLAGS_REG))]
8709   "TARGET_HIMODE_MATH"
8710   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8712 (define_insn "*iorhi_1"
8713   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8714         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8715                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8716    (clobber (reg:CC FLAGS_REG))]
8717   "ix86_binary_operator_ok (IOR, HImode, operands)"
8718   "or{w}\t{%2, %0|%0, %2}"
8719   [(set_attr "type" "alu")
8720    (set_attr "mode" "HI")])
8722 (define_insn "*iorhi_2"
8723   [(set (reg FLAGS_REG)
8724         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8725                          (match_operand:HI 2 "general_operand" "rim,ri"))
8726                  (const_int 0)))
8727    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8728         (ior:HI (match_dup 1) (match_dup 2)))]
8729   "ix86_match_ccmode (insn, CCNOmode)
8730    && ix86_binary_operator_ok (IOR, HImode, operands)"
8731   "or{w}\t{%2, %0|%0, %2}"
8732   [(set_attr "type" "alu")
8733    (set_attr "mode" "HI")])
8735 (define_insn "*iorhi_3"
8736   [(set (reg FLAGS_REG)
8737         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8738                          (match_operand:HI 2 "general_operand" "rim"))
8739                  (const_int 0)))
8740    (clobber (match_scratch:HI 0 "=r"))]
8741   "ix86_match_ccmode (insn, CCNOmode)
8742    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8743   "or{w}\t{%2, %0|%0, %2}"
8744   [(set_attr "type" "alu")
8745    (set_attr "mode" "HI")])
8747 (define_expand "iorqi3"
8748   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8749         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8750                 (match_operand:QI 2 "general_operand" "")))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "TARGET_QIMODE_MATH"
8753   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8755 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8756 (define_insn "*iorqi_1"
8757   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8758         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8759                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "ix86_binary_operator_ok (IOR, QImode, operands)"
8762   "@
8763    or{b}\t{%2, %0|%0, %2}
8764    or{b}\t{%2, %0|%0, %2}
8765    or{l}\t{%k2, %k0|%k0, %k2}"
8766   [(set_attr "type" "alu")
8767    (set_attr "mode" "QI,QI,SI")])
8769 (define_insn "*iorqi_1_slp"
8770   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8771         (ior:QI (match_dup 0)
8772                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8773    (clobber (reg:CC FLAGS_REG))]
8774   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8775    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8776   "or{b}\t{%1, %0|%0, %1}"
8777   [(set_attr "type" "alu1")
8778    (set_attr "mode" "QI")])
8780 (define_insn "*iorqi_2"
8781   [(set (reg FLAGS_REG)
8782         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8783                          (match_operand:QI 2 "general_operand" "qim,qi"))
8784                  (const_int 0)))
8785    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8786         (ior:QI (match_dup 1) (match_dup 2)))]
8787   "ix86_match_ccmode (insn, CCNOmode)
8788    && ix86_binary_operator_ok (IOR, QImode, operands)"
8789   "or{b}\t{%2, %0|%0, %2}"
8790   [(set_attr "type" "alu")
8791    (set_attr "mode" "QI")])
8793 (define_insn "*iorqi_2_slp"
8794   [(set (reg FLAGS_REG)
8795         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8796                          (match_operand:QI 1 "general_operand" "qim,qi"))
8797                  (const_int 0)))
8798    (set (strict_low_part (match_dup 0))
8799         (ior:QI (match_dup 0) (match_dup 1)))]
8800   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8801    && ix86_match_ccmode (insn, CCNOmode)
8802    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8803   "or{b}\t{%1, %0|%0, %1}"
8804   [(set_attr "type" "alu1")
8805    (set_attr "mode" "QI")])
8807 (define_insn "*iorqi_3"
8808   [(set (reg FLAGS_REG)
8809         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8810                          (match_operand:QI 2 "general_operand" "qim"))
8811                  (const_int 0)))
8812    (clobber (match_scratch:QI 0 "=q"))]
8813   "ix86_match_ccmode (insn, CCNOmode)
8814    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8815   "or{b}\t{%2, %0|%0, %2}"
8816   [(set_attr "type" "alu")
8817    (set_attr "mode" "QI")])
8819 (define_insn "iorqi_ext_0"
8820   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821                          (const_int 8)
8822                          (const_int 8))
8823         (ior:SI
8824           (zero_extract:SI
8825             (match_operand 1 "ext_register_operand" "0")
8826             (const_int 8)
8827             (const_int 8))
8828           (match_operand 2 "const_int_operand" "n")))
8829    (clobber (reg:CC FLAGS_REG))]
8830   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8831   "or{b}\t{%2, %h0|%h0, %2}"
8832   [(set_attr "type" "alu")
8833    (set_attr "length_immediate" "1")
8834    (set_attr "mode" "QI")])
8836 (define_insn "*iorqi_ext_1"
8837   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8838                          (const_int 8)
8839                          (const_int 8))
8840         (ior:SI
8841           (zero_extract:SI
8842             (match_operand 1 "ext_register_operand" "0")
8843             (const_int 8)
8844             (const_int 8))
8845           (zero_extend:SI
8846             (match_operand:QI 2 "general_operand" "Qm"))))
8847    (clobber (reg:CC FLAGS_REG))]
8848   "!TARGET_64BIT
8849    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8850   "or{b}\t{%2, %h0|%h0, %2}"
8851   [(set_attr "type" "alu")
8852    (set_attr "length_immediate" "0")
8853    (set_attr "mode" "QI")])
8855 (define_insn "*iorqi_ext_1_rex64"
8856   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8857                          (const_int 8)
8858                          (const_int 8))
8859         (ior:SI
8860           (zero_extract:SI
8861             (match_operand 1 "ext_register_operand" "0")
8862             (const_int 8)
8863             (const_int 8))
8864           (zero_extend:SI
8865             (match_operand 2 "ext_register_operand" "Q"))))
8866    (clobber (reg:CC FLAGS_REG))]
8867   "TARGET_64BIT
8868    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8869   "or{b}\t{%2, %h0|%h0, %2}"
8870   [(set_attr "type" "alu")
8871    (set_attr "length_immediate" "0")
8872    (set_attr "mode" "QI")])
8874 (define_insn "*iorqi_ext_2"
8875   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8876                          (const_int 8)
8877                          (const_int 8))
8878         (ior:SI
8879           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8880                            (const_int 8)
8881                            (const_int 8))
8882           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8883                            (const_int 8)
8884                            (const_int 8))))
8885    (clobber (reg:CC FLAGS_REG))]
8886   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8887   "ior{b}\t{%h2, %h0|%h0, %h2}"
8888   [(set_attr "type" "alu")
8889    (set_attr "length_immediate" "0")
8890    (set_attr "mode" "QI")])
8892 (define_split
8893   [(set (match_operand 0 "register_operand" "")
8894         (ior (match_operand 1 "register_operand" "")
8895              (match_operand 2 "const_int_operand" "")))
8896    (clobber (reg:CC FLAGS_REG))]
8897    "reload_completed
8898     && QI_REG_P (operands[0])
8899     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8900     && !(INTVAL (operands[2]) & ~(255 << 8))
8901     && GET_MODE (operands[0]) != QImode"
8902   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8903                    (ior:SI (zero_extract:SI (match_dup 1)
8904                                             (const_int 8) (const_int 8))
8905                            (match_dup 2)))
8906               (clobber (reg:CC FLAGS_REG))])]
8907   "operands[0] = gen_lowpart (SImode, operands[0]);
8908    operands[1] = gen_lowpart (SImode, operands[1]);
8909    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8911 ;; Since OR can be encoded with sign extended immediate, this is only
8912 ;; profitable when 7th bit is set.
8913 (define_split
8914   [(set (match_operand 0 "register_operand" "")
8915         (ior (match_operand 1 "general_operand" "")
8916              (match_operand 2 "const_int_operand" "")))
8917    (clobber (reg:CC FLAGS_REG))]
8918    "reload_completed
8919     && ANY_QI_REG_P (operands[0])
8920     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8921     && !(INTVAL (operands[2]) & ~255)
8922     && (INTVAL (operands[2]) & 128)
8923     && GET_MODE (operands[0]) != QImode"
8924   [(parallel [(set (strict_low_part (match_dup 0))
8925                    (ior:QI (match_dup 1)
8926                            (match_dup 2)))
8927               (clobber (reg:CC FLAGS_REG))])]
8928   "operands[0] = gen_lowpart (QImode, operands[0]);
8929    operands[1] = gen_lowpart (QImode, operands[1]);
8930    operands[2] = gen_lowpart (QImode, operands[2]);")
8932 ;; Logical XOR instructions
8934 ;; %%% This used to optimize known byte-wide and operations to memory.
8935 ;; If this is considered useful, it should be done with splitters.
8937 (define_expand "xordi3"
8938   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8939         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8940                 (match_operand:DI 2 "x86_64_general_operand" "")))
8941    (clobber (reg:CC FLAGS_REG))]
8942   "TARGET_64BIT"
8943   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8945 (define_insn "*xordi_1_rex64"
8946   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8947         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8948                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8949    (clobber (reg:CC FLAGS_REG))]
8950   "TARGET_64BIT
8951    && ix86_binary_operator_ok (XOR, DImode, operands)"
8952   "@
8953    xor{q}\t{%2, %0|%0, %2}
8954    xor{q}\t{%2, %0|%0, %2}"
8955   [(set_attr "type" "alu")
8956    (set_attr "mode" "DI,DI")])
8958 (define_insn "*xordi_2_rex64"
8959   [(set (reg FLAGS_REG)
8960         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8961                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8962                  (const_int 0)))
8963    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8964         (xor:DI (match_dup 1) (match_dup 2)))]
8965   "TARGET_64BIT
8966    && ix86_match_ccmode (insn, CCNOmode)
8967    && ix86_binary_operator_ok (XOR, DImode, operands)"
8968   "@
8969    xor{q}\t{%2, %0|%0, %2}
8970    xor{q}\t{%2, %0|%0, %2}"
8971   [(set_attr "type" "alu")
8972    (set_attr "mode" "DI,DI")])
8974 (define_insn "*xordi_3_rex64"
8975   [(set (reg FLAGS_REG)
8976         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8977                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8978                  (const_int 0)))
8979    (clobber (match_scratch:DI 0 "=r"))]
8980   "TARGET_64BIT
8981    && ix86_match_ccmode (insn, CCNOmode)
8982    && ix86_binary_operator_ok (XOR, DImode, operands)"
8983   "xor{q}\t{%2, %0|%0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "DI")])
8987 (define_expand "xorsi3"
8988   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8989         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8990                 (match_operand:SI 2 "general_operand" "")))
8991    (clobber (reg:CC FLAGS_REG))]
8992   ""
8993   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8995 (define_insn "*xorsi_1"
8996   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8997         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8998                 (match_operand:SI 2 "general_operand" "ri,rm")))
8999    (clobber (reg:CC FLAGS_REG))]
9000   "ix86_binary_operator_ok (XOR, SImode, operands)"
9001   "xor{l}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "SI")])
9005 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9006 ;; Add speccase for immediates
9007 (define_insn "*xorsi_1_zext"
9008   [(set (match_operand:DI 0 "register_operand" "=r")
9009         (zero_extend:DI
9010           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9011                   (match_operand:SI 2 "general_operand" "rim"))))
9012    (clobber (reg:CC FLAGS_REG))]
9013   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9014   "xor{l}\t{%2, %k0|%k0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "mode" "SI")])
9018 (define_insn "*xorsi_1_zext_imm"
9019   [(set (match_operand:DI 0 "register_operand" "=r")
9020         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9021                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9022    (clobber (reg:CC FLAGS_REG))]
9023   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9024   "xor{l}\t{%2, %k0|%k0, %2}"
9025   [(set_attr "type" "alu")
9026    (set_attr "mode" "SI")])
9028 (define_insn "*xorsi_2"
9029   [(set (reg FLAGS_REG)
9030         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9031                          (match_operand:SI 2 "general_operand" "rim,ri"))
9032                  (const_int 0)))
9033    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9034         (xor:SI (match_dup 1) (match_dup 2)))]
9035   "ix86_match_ccmode (insn, CCNOmode)
9036    && ix86_binary_operator_ok (XOR, SImode, operands)"
9037   "xor{l}\t{%2, %0|%0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "mode" "SI")])
9041 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9042 ;; ??? Special case for immediate operand is missing - it is tricky.
9043 (define_insn "*xorsi_2_zext"
9044   [(set (reg FLAGS_REG)
9045         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9046                          (match_operand:SI 2 "general_operand" "rim"))
9047                  (const_int 0)))
9048    (set (match_operand:DI 0 "register_operand" "=r")
9049         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9050   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9051    && ix86_binary_operator_ok (XOR, SImode, operands)"
9052   "xor{l}\t{%2, %k0|%k0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "SI")])
9056 (define_insn "*xorsi_2_zext_imm"
9057   [(set (reg FLAGS_REG)
9058         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9059                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9060                  (const_int 0)))
9061    (set (match_operand:DI 0 "register_operand" "=r")
9062         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9063   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9064    && ix86_binary_operator_ok (XOR, SImode, operands)"
9065   "xor{l}\t{%2, %k0|%k0, %2}"
9066   [(set_attr "type" "alu")
9067    (set_attr "mode" "SI")])
9069 (define_insn "*xorsi_3"
9070   [(set (reg FLAGS_REG)
9071         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9072                          (match_operand:SI 2 "general_operand" "rim"))
9073                  (const_int 0)))
9074    (clobber (match_scratch:SI 0 "=r"))]
9075   "ix86_match_ccmode (insn, CCNOmode)
9076    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9077   "xor{l}\t{%2, %0|%0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "mode" "SI")])
9081 (define_expand "xorhi3"
9082   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9083         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9084                 (match_operand:HI 2 "general_operand" "")))
9085    (clobber (reg:CC FLAGS_REG))]
9086   "TARGET_HIMODE_MATH"
9087   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9089 (define_insn "*xorhi_1"
9090   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9091         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9092                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "ix86_binary_operator_ok (XOR, HImode, operands)"
9095   "xor{w}\t{%2, %0|%0, %2}"
9096   [(set_attr "type" "alu")
9097    (set_attr "mode" "HI")])
9099 (define_insn "*xorhi_2"
9100   [(set (reg FLAGS_REG)
9101         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9102                          (match_operand:HI 2 "general_operand" "rim,ri"))
9103                  (const_int 0)))
9104    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9105         (xor:HI (match_dup 1) (match_dup 2)))]
9106   "ix86_match_ccmode (insn, CCNOmode)
9107    && ix86_binary_operator_ok (XOR, HImode, operands)"
9108   "xor{w}\t{%2, %0|%0, %2}"
9109   [(set_attr "type" "alu")
9110    (set_attr "mode" "HI")])
9112 (define_insn "*xorhi_3"
9113   [(set (reg FLAGS_REG)
9114         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9115                          (match_operand:HI 2 "general_operand" "rim"))
9116                  (const_int 0)))
9117    (clobber (match_scratch:HI 0 "=r"))]
9118   "ix86_match_ccmode (insn, CCNOmode)
9119    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9120   "xor{w}\t{%2, %0|%0, %2}"
9121   [(set_attr "type" "alu")
9122    (set_attr "mode" "HI")])
9124 (define_expand "xorqi3"
9125   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9126         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9127                 (match_operand:QI 2 "general_operand" "")))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "TARGET_QIMODE_MATH"
9130   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9132 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9133 (define_insn "*xorqi_1"
9134   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9135         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9136                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "ix86_binary_operator_ok (XOR, QImode, operands)"
9139   "@
9140    xor{b}\t{%2, %0|%0, %2}
9141    xor{b}\t{%2, %0|%0, %2}
9142    xor{l}\t{%k2, %k0|%k0, %k2}"
9143   [(set_attr "type" "alu")
9144    (set_attr "mode" "QI,QI,SI")])
9146 (define_insn "*xorqi_1_slp"
9147   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9148         (xor:QI (match_dup 0)
9149                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9150    (clobber (reg:CC FLAGS_REG))]
9151   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9152    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9153   "xor{b}\t{%1, %0|%0, %1}"
9154   [(set_attr "type" "alu1")
9155    (set_attr "mode" "QI")])
9157 (define_insn "xorqi_ext_0"
9158   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159                          (const_int 8)
9160                          (const_int 8))
9161         (xor:SI
9162           (zero_extract:SI
9163             (match_operand 1 "ext_register_operand" "0")
9164             (const_int 8)
9165             (const_int 8))
9166           (match_operand 2 "const_int_operand" "n")))
9167    (clobber (reg:CC FLAGS_REG))]
9168   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9169   "xor{b}\t{%2, %h0|%h0, %2}"
9170   [(set_attr "type" "alu")
9171    (set_attr "length_immediate" "1")
9172    (set_attr "mode" "QI")])
9174 (define_insn "*xorqi_ext_1"
9175   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9176                          (const_int 8)
9177                          (const_int 8))
9178         (xor:SI
9179           (zero_extract:SI
9180             (match_operand 1 "ext_register_operand" "0")
9181             (const_int 8)
9182             (const_int 8))
9183           (zero_extend:SI
9184             (match_operand:QI 2 "general_operand" "Qm"))))
9185    (clobber (reg:CC FLAGS_REG))]
9186   "!TARGET_64BIT
9187    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9188   "xor{b}\t{%2, %h0|%h0, %2}"
9189   [(set_attr "type" "alu")
9190    (set_attr "length_immediate" "0")
9191    (set_attr "mode" "QI")])
9193 (define_insn "*xorqi_ext_1_rex64"
9194   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9195                          (const_int 8)
9196                          (const_int 8))
9197         (xor:SI
9198           (zero_extract:SI
9199             (match_operand 1 "ext_register_operand" "0")
9200             (const_int 8)
9201             (const_int 8))
9202           (zero_extend:SI
9203             (match_operand 2 "ext_register_operand" "Q"))))
9204    (clobber (reg:CC FLAGS_REG))]
9205   "TARGET_64BIT
9206    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9207   "xor{b}\t{%2, %h0|%h0, %2}"
9208   [(set_attr "type" "alu")
9209    (set_attr "length_immediate" "0")
9210    (set_attr "mode" "QI")])
9212 (define_insn "*xorqi_ext_2"
9213   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9214                          (const_int 8)
9215                          (const_int 8))
9216         (xor:SI
9217           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9218                            (const_int 8)
9219                            (const_int 8))
9220           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9221                            (const_int 8)
9222                            (const_int 8))))
9223    (clobber (reg:CC FLAGS_REG))]
9224   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9225   "xor{b}\t{%h2, %h0|%h0, %h2}"
9226   [(set_attr "type" "alu")
9227    (set_attr "length_immediate" "0")
9228    (set_attr "mode" "QI")])
9230 (define_insn "*xorqi_cc_1"
9231   [(set (reg FLAGS_REG)
9232         (compare
9233           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9234                   (match_operand:QI 2 "general_operand" "qim,qi"))
9235           (const_int 0)))
9236    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9237         (xor:QI (match_dup 1) (match_dup 2)))]
9238   "ix86_match_ccmode (insn, CCNOmode)
9239    && ix86_binary_operator_ok (XOR, QImode, operands)"
9240   "xor{b}\t{%2, %0|%0, %2}"
9241   [(set_attr "type" "alu")
9242    (set_attr "mode" "QI")])
9244 (define_insn "*xorqi_2_slp"
9245   [(set (reg FLAGS_REG)
9246         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9247                          (match_operand:QI 1 "general_operand" "qim,qi"))
9248                  (const_int 0)))
9249    (set (strict_low_part (match_dup 0))
9250         (xor:QI (match_dup 0) (match_dup 1)))]
9251   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9252    && ix86_match_ccmode (insn, CCNOmode)
9253    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9254   "xor{b}\t{%1, %0|%0, %1}"
9255   [(set_attr "type" "alu1")
9256    (set_attr "mode" "QI")])
9258 (define_insn "*xorqi_cc_2"
9259   [(set (reg FLAGS_REG)
9260         (compare
9261           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9262                   (match_operand:QI 2 "general_operand" "qim"))
9263           (const_int 0)))
9264    (clobber (match_scratch:QI 0 "=q"))]
9265   "ix86_match_ccmode (insn, CCNOmode)
9266    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9267   "xor{b}\t{%2, %0|%0, %2}"
9268   [(set_attr "type" "alu")
9269    (set_attr "mode" "QI")])
9271 (define_insn "*xorqi_cc_ext_1"
9272   [(set (reg FLAGS_REG)
9273         (compare
9274           (xor:SI
9275             (zero_extract:SI
9276               (match_operand 1 "ext_register_operand" "0")
9277               (const_int 8)
9278               (const_int 8))
9279             (match_operand:QI 2 "general_operand" "qmn"))
9280           (const_int 0)))
9281    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9282                          (const_int 8)
9283                          (const_int 8))
9284         (xor:SI
9285           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9286           (match_dup 2)))]
9287   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9288   "xor{b}\t{%2, %h0|%h0, %2}"
9289   [(set_attr "type" "alu")
9290    (set_attr "mode" "QI")])
9292 (define_insn "*xorqi_cc_ext_1_rex64"
9293   [(set (reg FLAGS_REG)
9294         (compare
9295           (xor:SI
9296             (zero_extract:SI
9297               (match_operand 1 "ext_register_operand" "0")
9298               (const_int 8)
9299               (const_int 8))
9300             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9301           (const_int 0)))
9302    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9303                          (const_int 8)
9304                          (const_int 8))
9305         (xor:SI
9306           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9307           (match_dup 2)))]
9308   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9309   "xor{b}\t{%2, %h0|%h0, %2}"
9310   [(set_attr "type" "alu")
9311    (set_attr "mode" "QI")])
9313 (define_expand "xorqi_cc_ext_1"
9314   [(parallel [
9315      (set (reg:CCNO FLAGS_REG)
9316           (compare:CCNO
9317             (xor:SI
9318               (zero_extract:SI
9319                 (match_operand 1 "ext_register_operand" "")
9320                 (const_int 8)
9321                 (const_int 8))
9322               (match_operand:QI 2 "general_operand" ""))
9323             (const_int 0)))
9324      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9325                            (const_int 8)
9326                            (const_int 8))
9327           (xor:SI
9328             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9329             (match_dup 2)))])]
9330   ""
9331   "")
9333 (define_split
9334   [(set (match_operand 0 "register_operand" "")
9335         (xor (match_operand 1 "register_operand" "")
9336              (match_operand 2 "const_int_operand" "")))
9337    (clobber (reg:CC FLAGS_REG))]
9338    "reload_completed
9339     && QI_REG_P (operands[0])
9340     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9341     && !(INTVAL (operands[2]) & ~(255 << 8))
9342     && GET_MODE (operands[0]) != QImode"
9343   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9344                    (xor:SI (zero_extract:SI (match_dup 1)
9345                                             (const_int 8) (const_int 8))
9346                            (match_dup 2)))
9347               (clobber (reg:CC FLAGS_REG))])]
9348   "operands[0] = gen_lowpart (SImode, operands[0]);
9349    operands[1] = gen_lowpart (SImode, operands[1]);
9350    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9352 ;; Since XOR can be encoded with sign extended immediate, this is only
9353 ;; profitable when 7th bit is set.
9354 (define_split
9355   [(set (match_operand 0 "register_operand" "")
9356         (xor (match_operand 1 "general_operand" "")
9357              (match_operand 2 "const_int_operand" "")))
9358    (clobber (reg:CC FLAGS_REG))]
9359    "reload_completed
9360     && ANY_QI_REG_P (operands[0])
9361     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9362     && !(INTVAL (operands[2]) & ~255)
9363     && (INTVAL (operands[2]) & 128)
9364     && GET_MODE (operands[0]) != QImode"
9365   [(parallel [(set (strict_low_part (match_dup 0))
9366                    (xor:QI (match_dup 1)
9367                            (match_dup 2)))
9368               (clobber (reg:CC FLAGS_REG))])]
9369   "operands[0] = gen_lowpart (QImode, operands[0]);
9370    operands[1] = gen_lowpart (QImode, operands[1]);
9371    operands[2] = gen_lowpart (QImode, operands[2]);")
9373 ;; Negation instructions
9375 (define_expand "negti2"
9376   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9377                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9378               (clobber (reg:CC FLAGS_REG))])]
9379   "TARGET_64BIT"
9380   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9382 (define_insn "*negti2_1"
9383   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9384         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9385    (clobber (reg:CC FLAGS_REG))]
9386   "TARGET_64BIT
9387    && ix86_unary_operator_ok (NEG, TImode, operands)"
9388   "#")
9390 (define_split
9391   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9392         (neg:TI (match_operand:TI 1 "general_operand" "")))
9393    (clobber (reg:CC FLAGS_REG))]
9394   "TARGET_64BIT && reload_completed"
9395   [(parallel
9396     [(set (reg:CCZ FLAGS_REG)
9397           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9398      (set (match_dup 0) (neg:DI (match_dup 2)))])
9399    (parallel
9400     [(set (match_dup 1)
9401           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9402                             (match_dup 3))
9403                    (const_int 0)))
9404      (clobber (reg:CC FLAGS_REG))])
9405    (parallel
9406     [(set (match_dup 1)
9407           (neg:DI (match_dup 1)))
9408      (clobber (reg:CC FLAGS_REG))])]
9409   "split_ti (operands+1, 1, operands+2, operands+3);
9410    split_ti (operands+0, 1, operands+0, operands+1);")
9412 (define_expand "negdi2"
9413   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9414                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9415               (clobber (reg:CC FLAGS_REG))])]
9416   ""
9417   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9419 (define_insn "*negdi2_1"
9420   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9421         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9422    (clobber (reg:CC FLAGS_REG))]
9423   "!TARGET_64BIT
9424    && ix86_unary_operator_ok (NEG, DImode, operands)"
9425   "#")
9427 (define_split
9428   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9429         (neg:DI (match_operand:DI 1 "general_operand" "")))
9430    (clobber (reg:CC FLAGS_REG))]
9431   "!TARGET_64BIT && reload_completed"
9432   [(parallel
9433     [(set (reg:CCZ FLAGS_REG)
9434           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9435      (set (match_dup 0) (neg:SI (match_dup 2)))])
9436    (parallel
9437     [(set (match_dup 1)
9438           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9439                             (match_dup 3))
9440                    (const_int 0)))
9441      (clobber (reg:CC FLAGS_REG))])
9442    (parallel
9443     [(set (match_dup 1)
9444           (neg:SI (match_dup 1)))
9445      (clobber (reg:CC FLAGS_REG))])]
9446   "split_di (operands+1, 1, operands+2, operands+3);
9447    split_di (operands+0, 1, operands+0, operands+1);")
9449 (define_insn "*negdi2_1_rex64"
9450   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9451         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9452    (clobber (reg:CC FLAGS_REG))]
9453   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9454   "neg{q}\t%0"
9455   [(set_attr "type" "negnot")
9456    (set_attr "mode" "DI")])
9458 ;; The problem with neg is that it does not perform (compare x 0),
9459 ;; it really performs (compare 0 x), which leaves us with the zero
9460 ;; flag being the only useful item.
9462 (define_insn "*negdi2_cmpz_rex64"
9463   [(set (reg:CCZ FLAGS_REG)
9464         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9465                      (const_int 0)))
9466    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9467         (neg:DI (match_dup 1)))]
9468   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9469   "neg{q}\t%0"
9470   [(set_attr "type" "negnot")
9471    (set_attr "mode" "DI")])
9474 (define_expand "negsi2"
9475   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9476                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9477               (clobber (reg:CC FLAGS_REG))])]
9478   ""
9479   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9481 (define_insn "*negsi2_1"
9482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9483         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9484    (clobber (reg:CC FLAGS_REG))]
9485   "ix86_unary_operator_ok (NEG, SImode, operands)"
9486   "neg{l}\t%0"
9487   [(set_attr "type" "negnot")
9488    (set_attr "mode" "SI")])
9490 ;; Combine is quite creative about this pattern.
9491 (define_insn "*negsi2_1_zext"
9492   [(set (match_operand:DI 0 "register_operand" "=r")
9493         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9494                                         (const_int 32)))
9495                      (const_int 32)))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9498   "neg{l}\t%k0"
9499   [(set_attr "type" "negnot")
9500    (set_attr "mode" "SI")])
9502 ;; The problem with neg is that it does not perform (compare x 0),
9503 ;; it really performs (compare 0 x), which leaves us with the zero
9504 ;; flag being the only useful item.
9506 (define_insn "*negsi2_cmpz"
9507   [(set (reg:CCZ FLAGS_REG)
9508         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9509                      (const_int 0)))
9510    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9511         (neg:SI (match_dup 1)))]
9512   "ix86_unary_operator_ok (NEG, SImode, operands)"
9513   "neg{l}\t%0"
9514   [(set_attr "type" "negnot")
9515    (set_attr "mode" "SI")])
9517 (define_insn "*negsi2_cmpz_zext"
9518   [(set (reg:CCZ FLAGS_REG)
9519         (compare:CCZ (lshiftrt:DI
9520                        (neg:DI (ashift:DI
9521                                  (match_operand:DI 1 "register_operand" "0")
9522                                  (const_int 32)))
9523                        (const_int 32))
9524                      (const_int 0)))
9525    (set (match_operand:DI 0 "register_operand" "=r")
9526         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9527                                         (const_int 32)))
9528                      (const_int 32)))]
9529   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9530   "neg{l}\t%k0"
9531   [(set_attr "type" "negnot")
9532    (set_attr "mode" "SI")])
9534 (define_expand "neghi2"
9535   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9536                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9537               (clobber (reg:CC FLAGS_REG))])]
9538   "TARGET_HIMODE_MATH"
9539   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9541 (define_insn "*neghi2_1"
9542   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9543         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9544    (clobber (reg:CC FLAGS_REG))]
9545   "ix86_unary_operator_ok (NEG, HImode, operands)"
9546   "neg{w}\t%0"
9547   [(set_attr "type" "negnot")
9548    (set_attr "mode" "HI")])
9550 (define_insn "*neghi2_cmpz"
9551   [(set (reg:CCZ FLAGS_REG)
9552         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9553                      (const_int 0)))
9554    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9555         (neg:HI (match_dup 1)))]
9556   "ix86_unary_operator_ok (NEG, HImode, operands)"
9557   "neg{w}\t%0"
9558   [(set_attr "type" "negnot")
9559    (set_attr "mode" "HI")])
9561 (define_expand "negqi2"
9562   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9563                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9564               (clobber (reg:CC FLAGS_REG))])]
9565   "TARGET_QIMODE_MATH"
9566   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9568 (define_insn "*negqi2_1"
9569   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9570         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9571    (clobber (reg:CC FLAGS_REG))]
9572   "ix86_unary_operator_ok (NEG, QImode, operands)"
9573   "neg{b}\t%0"
9574   [(set_attr "type" "negnot")
9575    (set_attr "mode" "QI")])
9577 (define_insn "*negqi2_cmpz"
9578   [(set (reg:CCZ FLAGS_REG)
9579         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9580                      (const_int 0)))
9581    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9582         (neg:QI (match_dup 1)))]
9583   "ix86_unary_operator_ok (NEG, QImode, operands)"
9584   "neg{b}\t%0"
9585   [(set_attr "type" "negnot")
9586    (set_attr "mode" "QI")])
9588 ;; Changing of sign for FP values is doable using integer unit too.
9590 (define_expand "negsf2"
9591   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9592         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9593   "TARGET_80387 || TARGET_SSE_MATH"
9594   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9596 (define_expand "abssf2"
9597   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9598         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9599   "TARGET_80387 || TARGET_SSE_MATH"
9600   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9602 (define_insn "*absnegsf2_mixed"
9603   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9604         (match_operator:SF 3 "absneg_operator"
9605           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9606    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9607    (clobber (reg:CC FLAGS_REG))]
9608   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9609    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9610   "#")
9612 (define_insn "*absnegsf2_sse"
9613   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9614         (match_operator:SF 3 "absneg_operator"
9615           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9616    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9617    (clobber (reg:CC FLAGS_REG))]
9618   "TARGET_SSE_MATH
9619    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9620   "#")
9622 (define_insn "*absnegsf2_i387"
9623   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9624         (match_operator:SF 3 "absneg_operator"
9625           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9626    (use (match_operand 2 "" ""))
9627    (clobber (reg:CC FLAGS_REG))]
9628   "TARGET_80387 && !TARGET_SSE_MATH
9629    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9630   "#")
9632 (define_expand "copysignsf3"
9633   [(match_operand:SF 0 "register_operand" "")
9634    (match_operand:SF 1 "nonmemory_operand" "")
9635    (match_operand:SF 2 "register_operand" "")]
9636   "TARGET_SSE_MATH"
9638   ix86_expand_copysign (operands);
9639   DONE;
9642 (define_insn_and_split "copysignsf3_const"
9643   [(set (match_operand:SF 0 "register_operand"          "=x")
9644         (unspec:SF
9645           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9646            (match_operand:SF 2 "register_operand"       "0")
9647            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9648           UNSPEC_COPYSIGN))]
9649   "TARGET_SSE_MATH"
9650   "#"
9651   "&& reload_completed"
9652   [(const_int 0)]
9654   ix86_split_copysign_const (operands);
9655   DONE;
9658 (define_insn "copysignsf3_var"
9659   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9660         (unspec:SF
9661           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9662            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9663            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9664            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9665           UNSPEC_COPYSIGN))
9666    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9667   "TARGET_SSE_MATH"
9668   "#")
9670 (define_split
9671   [(set (match_operand:SF 0 "register_operand" "")
9672         (unspec:SF
9673           [(match_operand:SF 2 "register_operand" "")
9674            (match_operand:SF 3 "register_operand" "")
9675            (match_operand:V4SF 4 "" "")
9676            (match_operand:V4SF 5 "" "")]
9677           UNSPEC_COPYSIGN))
9678    (clobber (match_scratch:V4SF 1 ""))]
9679   "TARGET_SSE_MATH && reload_completed"
9680   [(const_int 0)]
9682   ix86_split_copysign_var (operands);
9683   DONE;
9686 (define_expand "negdf2"
9687   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9688         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9689   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9690   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9692 (define_expand "absdf2"
9693   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9694         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9695   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9696   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9698 (define_insn "*absnegdf2_mixed"
9699   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9700         (match_operator:DF 3 "absneg_operator"
9701           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9702    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9703    (clobber (reg:CC FLAGS_REG))]
9704   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9705    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9706   "#")
9708 (define_insn "*absnegdf2_sse"
9709   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9710         (match_operator:DF 3 "absneg_operator"
9711           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9712    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9713    (clobber (reg:CC FLAGS_REG))]
9714   "TARGET_SSE2 && TARGET_SSE_MATH
9715    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9716   "#")
9718 (define_insn "*absnegdf2_i387"
9719   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9720         (match_operator:DF 3 "absneg_operator"
9721           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9722    (use (match_operand 2 "" ""))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9725    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9726   "#")
9728 (define_expand "copysigndf3"
9729   [(match_operand:DF 0 "register_operand" "")
9730    (match_operand:DF 1 "nonmemory_operand" "")
9731    (match_operand:DF 2 "register_operand" "")]
9732   "TARGET_SSE2 && TARGET_SSE_MATH"
9734   ix86_expand_copysign (operands);
9735   DONE;
9738 (define_insn_and_split "copysigndf3_const"
9739   [(set (match_operand:DF 0 "register_operand"          "=x")
9740         (unspec:DF
9741           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9742            (match_operand:DF 2 "register_operand"       "0")
9743            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9744           UNSPEC_COPYSIGN))]
9745   "TARGET_SSE2 && TARGET_SSE_MATH"
9746   "#"
9747   "&& reload_completed"
9748   [(const_int 0)]
9750   ix86_split_copysign_const (operands);
9751   DONE;
9754 (define_insn "copysigndf3_var"
9755   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9756         (unspec:DF
9757           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9758            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9759            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9760            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9761           UNSPEC_COPYSIGN))
9762    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9763   "TARGET_SSE2 && TARGET_SSE_MATH"
9764   "#")
9766 (define_split
9767   [(set (match_operand:DF 0 "register_operand" "")
9768         (unspec:DF
9769           [(match_operand:DF 2 "register_operand" "")
9770            (match_operand:DF 3 "register_operand" "")
9771            (match_operand:V2DF 4 "" "")
9772            (match_operand:V2DF 5 "" "")]
9773           UNSPEC_COPYSIGN))
9774    (clobber (match_scratch:V2DF 1 ""))]
9775   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9776   [(const_int 0)]
9778   ix86_split_copysign_var (operands);
9779   DONE;
9782 (define_expand "negxf2"
9783   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9784         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9785   "TARGET_80387"
9786   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9788 (define_expand "absxf2"
9789   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9790         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9791   "TARGET_80387"
9792   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9794 (define_insn "*absnegxf2_i387"
9795   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9796         (match_operator:XF 3 "absneg_operator"
9797           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9798    (use (match_operand 2 "" ""))
9799    (clobber (reg:CC FLAGS_REG))]
9800   "TARGET_80387
9801    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9802   "#")
9804 ;; Splitters for fp abs and neg.
9806 (define_split
9807   [(set (match_operand 0 "fp_register_operand" "")
9808         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9809    (use (match_operand 2 "" ""))
9810    (clobber (reg:CC FLAGS_REG))]
9811   "reload_completed"
9812   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9814 (define_split
9815   [(set (match_operand 0 "register_operand" "")
9816         (match_operator 3 "absneg_operator"
9817           [(match_operand 1 "register_operand" "")]))
9818    (use (match_operand 2 "nonimmediate_operand" ""))
9819    (clobber (reg:CC FLAGS_REG))]
9820   "reload_completed && SSE_REG_P (operands[0])"
9821   [(set (match_dup 0) (match_dup 3))]
9823   enum machine_mode mode = GET_MODE (operands[0]);
9824   enum machine_mode vmode = GET_MODE (operands[2]);
9825   rtx tmp;
9827   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9828   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9829   if (operands_match_p (operands[0], operands[2]))
9830     {
9831       tmp = operands[1];
9832       operands[1] = operands[2];
9833       operands[2] = tmp;
9834     }
9835   if (GET_CODE (operands[3]) == ABS)
9836     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9837   else
9838     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9839   operands[3] = tmp;
9842 (define_split
9843   [(set (match_operand:SF 0 "register_operand" "")
9844         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9845    (use (match_operand:V4SF 2 "" ""))
9846    (clobber (reg:CC FLAGS_REG))]
9847   "reload_completed"
9848   [(parallel [(set (match_dup 0) (match_dup 1))
9849               (clobber (reg:CC FLAGS_REG))])]
9851   rtx tmp;
9852   operands[0] = gen_lowpart (SImode, operands[0]);
9853   if (GET_CODE (operands[1]) == ABS)
9854     {
9855       tmp = gen_int_mode (0x7fffffff, SImode);
9856       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9857     }
9858   else
9859     {
9860       tmp = gen_int_mode (0x80000000, SImode);
9861       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9862     }
9863   operands[1] = tmp;
9866 (define_split
9867   [(set (match_operand:DF 0 "register_operand" "")
9868         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9869    (use (match_operand 2 "" ""))
9870    (clobber (reg:CC FLAGS_REG))]
9871   "reload_completed"
9872   [(parallel [(set (match_dup 0) (match_dup 1))
9873               (clobber (reg:CC FLAGS_REG))])]
9875   rtx tmp;
9876   if (TARGET_64BIT)
9877     {
9878       tmp = gen_lowpart (DImode, operands[0]);
9879       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9880       operands[0] = tmp;
9882       if (GET_CODE (operands[1]) == ABS)
9883         tmp = const0_rtx;
9884       else
9885         tmp = gen_rtx_NOT (DImode, tmp);
9886     }
9887   else
9888     {
9889       operands[0] = gen_highpart (SImode, operands[0]);
9890       if (GET_CODE (operands[1]) == ABS)
9891         {
9892           tmp = gen_int_mode (0x7fffffff, SImode);
9893           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9894         }
9895       else
9896         {
9897           tmp = gen_int_mode (0x80000000, SImode);
9898           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9899         }
9900     }
9901   operands[1] = tmp;
9904 (define_split
9905   [(set (match_operand:XF 0 "register_operand" "")
9906         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9907    (use (match_operand 2 "" ""))
9908    (clobber (reg:CC FLAGS_REG))]
9909   "reload_completed"
9910   [(parallel [(set (match_dup 0) (match_dup 1))
9911               (clobber (reg:CC FLAGS_REG))])]
9913   rtx tmp;
9914   operands[0] = gen_rtx_REG (SImode,
9915                              true_regnum (operands[0])
9916                              + (TARGET_64BIT ? 1 : 2));
9917   if (GET_CODE (operands[1]) == ABS)
9918     {
9919       tmp = GEN_INT (0x7fff);
9920       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9921     }
9922   else
9923     {
9924       tmp = GEN_INT (0x8000);
9925       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9926     }
9927   operands[1] = tmp;
9930 (define_split
9931   [(set (match_operand 0 "memory_operand" "")
9932         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9933    (use (match_operand 2 "" ""))
9934    (clobber (reg:CC FLAGS_REG))]
9935   "reload_completed"
9936   [(parallel [(set (match_dup 0) (match_dup 1))
9937               (clobber (reg:CC FLAGS_REG))])]
9939   enum machine_mode mode = GET_MODE (operands[0]);
9940   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9941   rtx tmp;
9943   operands[0] = adjust_address (operands[0], QImode, size - 1);
9944   if (GET_CODE (operands[1]) == ABS)
9945     {
9946       tmp = gen_int_mode (0x7f, QImode);
9947       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9948     }
9949   else
9950     {
9951       tmp = gen_int_mode (0x80, QImode);
9952       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9953     }
9954   operands[1] = tmp;
9957 ;; Conditionalize these after reload. If they match before reload, we
9958 ;; lose the clobber and ability to use integer instructions.
9960 (define_insn "*negsf2_1"
9961   [(set (match_operand:SF 0 "register_operand" "=f")
9962         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9963   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9964   "fchs"
9965   [(set_attr "type" "fsgn")
9966    (set_attr "mode" "SF")])
9968 (define_insn "*negdf2_1"
9969   [(set (match_operand:DF 0 "register_operand" "=f")
9970         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9971   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9972   "fchs"
9973   [(set_attr "type" "fsgn")
9974    (set_attr "mode" "DF")])
9976 (define_insn "*negxf2_1"
9977   [(set (match_operand:XF 0 "register_operand" "=f")
9978         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9979   "TARGET_80387"
9980   "fchs"
9981   [(set_attr "type" "fsgn")
9982    (set_attr "mode" "XF")])
9984 (define_insn "*abssf2_1"
9985   [(set (match_operand:SF 0 "register_operand" "=f")
9986         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9987   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9988   "fabs"
9989   [(set_attr "type" "fsgn")
9990    (set_attr "mode" "SF")])
9992 (define_insn "*absdf2_1"
9993   [(set (match_operand:DF 0 "register_operand" "=f")
9994         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9995   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9996   "fabs"
9997   [(set_attr "type" "fsgn")
9998    (set_attr "mode" "DF")])
10000 (define_insn "*absxf2_1"
10001   [(set (match_operand:XF 0 "register_operand" "=f")
10002         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10003   "TARGET_80387"
10004   "fabs"
10005   [(set_attr "type" "fsgn")
10006    (set_attr "mode" "DF")])
10008 (define_insn "*negextendsfdf2"
10009   [(set (match_operand:DF 0 "register_operand" "=f")
10010         (neg:DF (float_extend:DF
10011                   (match_operand:SF 1 "register_operand" "0"))))]
10012   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10013   "fchs"
10014   [(set_attr "type" "fsgn")
10015    (set_attr "mode" "DF")])
10017 (define_insn "*negextenddfxf2"
10018   [(set (match_operand:XF 0 "register_operand" "=f")
10019         (neg:XF (float_extend:XF
10020                   (match_operand:DF 1 "register_operand" "0"))))]
10021   "TARGET_80387"
10022   "fchs"
10023   [(set_attr "type" "fsgn")
10024    (set_attr "mode" "XF")])
10026 (define_insn "*negextendsfxf2"
10027   [(set (match_operand:XF 0 "register_operand" "=f")
10028         (neg:XF (float_extend:XF
10029                   (match_operand:SF 1 "register_operand" "0"))))]
10030   "TARGET_80387"
10031   "fchs"
10032   [(set_attr "type" "fsgn")
10033    (set_attr "mode" "XF")])
10035 (define_insn "*absextendsfdf2"
10036   [(set (match_operand:DF 0 "register_operand" "=f")
10037         (abs:DF (float_extend:DF
10038                   (match_operand:SF 1 "register_operand" "0"))))]
10039   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10040   "fabs"
10041   [(set_attr "type" "fsgn")
10042    (set_attr "mode" "DF")])
10044 (define_insn "*absextenddfxf2"
10045   [(set (match_operand:XF 0 "register_operand" "=f")
10046         (abs:XF (float_extend:XF
10047           (match_operand:DF 1 "register_operand" "0"))))]
10048   "TARGET_80387"
10049   "fabs"
10050   [(set_attr "type" "fsgn")
10051    (set_attr "mode" "XF")])
10053 (define_insn "*absextendsfxf2"
10054   [(set (match_operand:XF 0 "register_operand" "=f")
10055         (abs:XF (float_extend:XF
10056           (match_operand:SF 1 "register_operand" "0"))))]
10057   "TARGET_80387"
10058   "fabs"
10059   [(set_attr "type" "fsgn")
10060    (set_attr "mode" "XF")])
10062 ;; One complement instructions
10064 (define_expand "one_cmpldi2"
10065   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10066         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10067   "TARGET_64BIT"
10068   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10070 (define_insn "*one_cmpldi2_1_rex64"
10071   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10072         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10073   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10074   "not{q}\t%0"
10075   [(set_attr "type" "negnot")
10076    (set_attr "mode" "DI")])
10078 (define_insn "*one_cmpldi2_2_rex64"
10079   [(set (reg FLAGS_REG)
10080         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10081                  (const_int 0)))
10082    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10083         (not:DI (match_dup 1)))]
10084   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10085    && ix86_unary_operator_ok (NOT, DImode, operands)"
10086   "#"
10087   [(set_attr "type" "alu1")
10088    (set_attr "mode" "DI")])
10090 (define_split
10091   [(set (match_operand 0 "flags_reg_operand" "")
10092         (match_operator 2 "compare_operator"
10093           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10094            (const_int 0)]))
10095    (set (match_operand:DI 1 "nonimmediate_operand" "")
10096         (not:DI (match_dup 3)))]
10097   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10098   [(parallel [(set (match_dup 0)
10099                    (match_op_dup 2
10100                      [(xor:DI (match_dup 3) (const_int -1))
10101                       (const_int 0)]))
10102               (set (match_dup 1)
10103                    (xor:DI (match_dup 3) (const_int -1)))])]
10104   "")
10106 (define_expand "one_cmplsi2"
10107   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10108         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10109   ""
10110   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10112 (define_insn "*one_cmplsi2_1"
10113   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10114         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10115   "ix86_unary_operator_ok (NOT, SImode, operands)"
10116   "not{l}\t%0"
10117   [(set_attr "type" "negnot")
10118    (set_attr "mode" "SI")])
10120 ;; ??? Currently never generated - xor is used instead.
10121 (define_insn "*one_cmplsi2_1_zext"
10122   [(set (match_operand:DI 0 "register_operand" "=r")
10123         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10124   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10125   "not{l}\t%k0"
10126   [(set_attr "type" "negnot")
10127    (set_attr "mode" "SI")])
10129 (define_insn "*one_cmplsi2_2"
10130   [(set (reg FLAGS_REG)
10131         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10132                  (const_int 0)))
10133    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10134         (not:SI (match_dup 1)))]
10135   "ix86_match_ccmode (insn, CCNOmode)
10136    && ix86_unary_operator_ok (NOT, SImode, operands)"
10137   "#"
10138   [(set_attr "type" "alu1")
10139    (set_attr "mode" "SI")])
10141 (define_split
10142   [(set (match_operand 0 "flags_reg_operand" "")
10143         (match_operator 2 "compare_operator"
10144           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10145            (const_int 0)]))
10146    (set (match_operand:SI 1 "nonimmediate_operand" "")
10147         (not:SI (match_dup 3)))]
10148   "ix86_match_ccmode (insn, CCNOmode)"
10149   [(parallel [(set (match_dup 0)
10150                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10151                                     (const_int 0)]))
10152               (set (match_dup 1)
10153                    (xor:SI (match_dup 3) (const_int -1)))])]
10154   "")
10156 ;; ??? Currently never generated - xor is used instead.
10157 (define_insn "*one_cmplsi2_2_zext"
10158   [(set (reg FLAGS_REG)
10159         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10160                  (const_int 0)))
10161    (set (match_operand:DI 0 "register_operand" "=r")
10162         (zero_extend:DI (not:SI (match_dup 1))))]
10163   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10164    && ix86_unary_operator_ok (NOT, SImode, operands)"
10165   "#"
10166   [(set_attr "type" "alu1")
10167    (set_attr "mode" "SI")])
10169 (define_split
10170   [(set (match_operand 0 "flags_reg_operand" "")
10171         (match_operator 2 "compare_operator"
10172           [(not:SI (match_operand:SI 3 "register_operand" ""))
10173            (const_int 0)]))
10174    (set (match_operand:DI 1 "register_operand" "")
10175         (zero_extend:DI (not:SI (match_dup 3))))]
10176   "ix86_match_ccmode (insn, CCNOmode)"
10177   [(parallel [(set (match_dup 0)
10178                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10179                                     (const_int 0)]))
10180               (set (match_dup 1)
10181                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10182   "")
10184 (define_expand "one_cmplhi2"
10185   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10186         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10187   "TARGET_HIMODE_MATH"
10188   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10190 (define_insn "*one_cmplhi2_1"
10191   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10192         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10193   "ix86_unary_operator_ok (NOT, HImode, operands)"
10194   "not{w}\t%0"
10195   [(set_attr "type" "negnot")
10196    (set_attr "mode" "HI")])
10198 (define_insn "*one_cmplhi2_2"
10199   [(set (reg FLAGS_REG)
10200         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10201                  (const_int 0)))
10202    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10203         (not:HI (match_dup 1)))]
10204   "ix86_match_ccmode (insn, CCNOmode)
10205    && ix86_unary_operator_ok (NEG, HImode, operands)"
10206   "#"
10207   [(set_attr "type" "alu1")
10208    (set_attr "mode" "HI")])
10210 (define_split
10211   [(set (match_operand 0 "flags_reg_operand" "")
10212         (match_operator 2 "compare_operator"
10213           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10214            (const_int 0)]))
10215    (set (match_operand:HI 1 "nonimmediate_operand" "")
10216         (not:HI (match_dup 3)))]
10217   "ix86_match_ccmode (insn, CCNOmode)"
10218   [(parallel [(set (match_dup 0)
10219                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10220                                     (const_int 0)]))
10221               (set (match_dup 1)
10222                    (xor:HI (match_dup 3) (const_int -1)))])]
10223   "")
10225 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10226 (define_expand "one_cmplqi2"
10227   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10228         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10229   "TARGET_QIMODE_MATH"
10230   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10232 (define_insn "*one_cmplqi2_1"
10233   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10234         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10235   "ix86_unary_operator_ok (NOT, QImode, operands)"
10236   "@
10237    not{b}\t%0
10238    not{l}\t%k0"
10239   [(set_attr "type" "negnot")
10240    (set_attr "mode" "QI,SI")])
10242 (define_insn "*one_cmplqi2_2"
10243   [(set (reg FLAGS_REG)
10244         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10245                  (const_int 0)))
10246    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10247         (not:QI (match_dup 1)))]
10248   "ix86_match_ccmode (insn, CCNOmode)
10249    && ix86_unary_operator_ok (NOT, QImode, operands)"
10250   "#"
10251   [(set_attr "type" "alu1")
10252    (set_attr "mode" "QI")])
10254 (define_split
10255   [(set (match_operand 0 "flags_reg_operand" "")
10256         (match_operator 2 "compare_operator"
10257           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10258            (const_int 0)]))
10259    (set (match_operand:QI 1 "nonimmediate_operand" "")
10260         (not:QI (match_dup 3)))]
10261   "ix86_match_ccmode (insn, CCNOmode)"
10262   [(parallel [(set (match_dup 0)
10263                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10264                                     (const_int 0)]))
10265               (set (match_dup 1)
10266                    (xor:QI (match_dup 3) (const_int -1)))])]
10267   "")
10269 ;; Arithmetic shift instructions
10271 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10272 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10273 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10274 ;; from the assembler input.
10276 ;; This instruction shifts the target reg/mem as usual, but instead of
10277 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10278 ;; is a left shift double, bits are taken from the high order bits of
10279 ;; reg, else if the insn is a shift right double, bits are taken from the
10280 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10281 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10283 ;; Since sh[lr]d does not change the `reg' operand, that is done
10284 ;; separately, making all shifts emit pairs of shift double and normal
10285 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10286 ;; support a 63 bit shift, each shift where the count is in a reg expands
10287 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10289 ;; If the shift count is a constant, we need never emit more than one
10290 ;; shift pair, instead using moves and sign extension for counts greater
10291 ;; than 31.
10293 (define_expand "ashlti3"
10294   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10295                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10296                               (match_operand:QI 2 "nonmemory_operand" "")))
10297               (clobber (reg:CC FLAGS_REG))])]
10298   "TARGET_64BIT"
10300   if (! immediate_operand (operands[2], QImode))
10301     {
10302       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10303       DONE;
10304     }
10305   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10306   DONE;
10309 (define_insn "ashlti3_1"
10310   [(set (match_operand:TI 0 "register_operand" "=r")
10311         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10312                    (match_operand:QI 2 "register_operand" "c")))
10313    (clobber (match_scratch:DI 3 "=&r"))
10314    (clobber (reg:CC FLAGS_REG))]
10315   "TARGET_64BIT"
10316   "#"
10317   [(set_attr "type" "multi")])
10319 (define_insn "*ashlti3_2"
10320   [(set (match_operand:TI 0 "register_operand" "=r")
10321         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10322                    (match_operand:QI 2 "immediate_operand" "O")))
10323    (clobber (reg:CC FLAGS_REG))]
10324   "TARGET_64BIT"
10325   "#"
10326   [(set_attr "type" "multi")])
10328 (define_split
10329   [(set (match_operand:TI 0 "register_operand" "")
10330         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10331                    (match_operand:QI 2 "register_operand" "")))
10332    (clobber (match_scratch:DI 3 ""))
10333    (clobber (reg:CC FLAGS_REG))]
10334   "TARGET_64BIT && reload_completed"
10335   [(const_int 0)]
10336   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10338 (define_split
10339   [(set (match_operand:TI 0 "register_operand" "")
10340         (ashift:TI (match_operand:TI 1 "register_operand" "")
10341                    (match_operand:QI 2 "immediate_operand" "")))
10342    (clobber (reg:CC FLAGS_REG))]
10343   "TARGET_64BIT && reload_completed"
10344   [(const_int 0)]
10345   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10347 (define_insn "x86_64_shld"
10348   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10349         (ior:DI (ashift:DI (match_dup 0)
10350                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10351                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10352                   (minus:QI (const_int 64) (match_dup 2)))))
10353    (clobber (reg:CC FLAGS_REG))]
10354   "TARGET_64BIT"
10355   "@
10356    shld{q}\t{%2, %1, %0|%0, %1, %2}
10357    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10358   [(set_attr "type" "ishift")
10359    (set_attr "prefix_0f" "1")
10360    (set_attr "mode" "DI")
10361    (set_attr "athlon_decode" "vector")])
10363 (define_expand "x86_64_shift_adj"
10364   [(set (reg:CCZ FLAGS_REG)
10365         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10366                              (const_int 64))
10367                      (const_int 0)))
10368    (set (match_operand:DI 0 "register_operand" "")
10369         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10370                          (match_operand:DI 1 "register_operand" "")
10371                          (match_dup 0)))
10372    (set (match_dup 1)
10373         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10374                          (match_operand:DI 3 "register_operand" "r")
10375                          (match_dup 1)))]
10376   "TARGET_64BIT"
10377   "")
10379 (define_expand "ashldi3"
10380   [(set (match_operand:DI 0 "shiftdi_operand" "")
10381         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10382                    (match_operand:QI 2 "nonmemory_operand" "")))]
10383   ""
10384   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10386 (define_insn "*ashldi3_1_rex64"
10387   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10388         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10389                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10390    (clobber (reg:CC FLAGS_REG))]
10391   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10393   switch (get_attr_type (insn))
10394     {
10395     case TYPE_ALU:
10396       gcc_assert (operands[2] == const1_rtx);
10397       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10398       return "add{q}\t{%0, %0|%0, %0}";
10400     case TYPE_LEA:
10401       gcc_assert (CONST_INT_P (operands[2]));
10402       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10403       operands[1] = gen_rtx_MULT (DImode, operands[1],
10404                                   GEN_INT (1 << INTVAL (operands[2])));
10405       return "lea{q}\t{%a1, %0|%0, %a1}";
10407     default:
10408       if (REG_P (operands[2]))
10409         return "sal{q}\t{%b2, %0|%0, %b2}";
10410       else if (operands[2] == const1_rtx
10411                && (TARGET_SHIFT1 || optimize_size))
10412         return "sal{q}\t%0";
10413       else
10414         return "sal{q}\t{%2, %0|%0, %2}";
10415     }
10417   [(set (attr "type")
10418      (cond [(eq_attr "alternative" "1")
10419               (const_string "lea")
10420             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10421                           (const_int 0))
10422                       (match_operand 0 "register_operand" ""))
10423                  (match_operand 2 "const1_operand" ""))
10424               (const_string "alu")
10425            ]
10426            (const_string "ishift")))
10427    (set_attr "mode" "DI")])
10429 ;; Convert lea to the lea pattern to avoid flags dependency.
10430 (define_split
10431   [(set (match_operand:DI 0 "register_operand" "")
10432         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10433                    (match_operand:QI 2 "immediate_operand" "")))
10434    (clobber (reg:CC FLAGS_REG))]
10435   "TARGET_64BIT && reload_completed
10436    && true_regnum (operands[0]) != true_regnum (operands[1])"
10437   [(set (match_dup 0)
10438         (mult:DI (match_dup 1)
10439                  (match_dup 2)))]
10440   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10442 ;; This pattern can't accept a variable shift count, since shifts by
10443 ;; zero don't affect the flags.  We assume that shifts by constant
10444 ;; zero are optimized away.
10445 (define_insn "*ashldi3_cmp_rex64"
10446   [(set (reg FLAGS_REG)
10447         (compare
10448           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10449                      (match_operand:QI 2 "immediate_operand" "e"))
10450           (const_int 0)))
10451    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10452         (ashift:DI (match_dup 1) (match_dup 2)))]
10453   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10454    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10455    && (optimize_size
10456        || !TARGET_PARTIAL_FLAG_REG_STALL
10457        || (operands[2] == const1_rtx
10458            && (TARGET_SHIFT1
10459                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10461   switch (get_attr_type (insn))
10462     {
10463     case TYPE_ALU:
10464       gcc_assert (operands[2] == const1_rtx);
10465       return "add{q}\t{%0, %0|%0, %0}";
10467     default:
10468       if (REG_P (operands[2]))
10469         return "sal{q}\t{%b2, %0|%0, %b2}";
10470       else if (operands[2] == const1_rtx
10471                && (TARGET_SHIFT1 || optimize_size))
10472         return "sal{q}\t%0";
10473       else
10474         return "sal{q}\t{%2, %0|%0, %2}";
10475     }
10477   [(set (attr "type")
10478      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10479                           (const_int 0))
10480                       (match_operand 0 "register_operand" ""))
10481                  (match_operand 2 "const1_operand" ""))
10482               (const_string "alu")
10483            ]
10484            (const_string "ishift")))
10485    (set_attr "mode" "DI")])
10487 (define_insn "*ashldi3_cconly_rex64"
10488   [(set (reg FLAGS_REG)
10489         (compare
10490           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10491                      (match_operand:QI 2 "immediate_operand" "e"))
10492           (const_int 0)))
10493    (clobber (match_scratch:DI 0 "=r"))]
10494   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10495    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10496    && (optimize_size
10497        || !TARGET_PARTIAL_FLAG_REG_STALL
10498        || (operands[2] == const1_rtx
10499            && (TARGET_SHIFT1
10500                || TARGET_DOUBLE_WITH_ADD)))"
10502   switch (get_attr_type (insn))
10503     {
10504     case TYPE_ALU:
10505       gcc_assert (operands[2] == const1_rtx);
10506       return "add{q}\t{%0, %0|%0, %0}";
10508     default:
10509       if (REG_P (operands[2]))
10510         return "sal{q}\t{%b2, %0|%0, %b2}";
10511       else if (operands[2] == const1_rtx
10512                && (TARGET_SHIFT1 || optimize_size))
10513         return "sal{q}\t%0";
10514       else
10515         return "sal{q}\t{%2, %0|%0, %2}";
10516     }
10518   [(set (attr "type")
10519      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10520                           (const_int 0))
10521                       (match_operand 0 "register_operand" ""))
10522                  (match_operand 2 "const1_operand" ""))
10523               (const_string "alu")
10524            ]
10525            (const_string "ishift")))
10526    (set_attr "mode" "DI")])
10528 (define_insn "*ashldi3_1"
10529   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10530         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10531                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10532    (clobber (reg:CC FLAGS_REG))]
10533   "!TARGET_64BIT"
10534   "#"
10535   [(set_attr "type" "multi")])
10537 ;; By default we don't ask for a scratch register, because when DImode
10538 ;; values are manipulated, registers are already at a premium.  But if
10539 ;; we have one handy, we won't turn it away.
10540 (define_peephole2
10541   [(match_scratch:SI 3 "r")
10542    (parallel [(set (match_operand:DI 0 "register_operand" "")
10543                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10544                               (match_operand:QI 2 "nonmemory_operand" "")))
10545               (clobber (reg:CC FLAGS_REG))])
10546    (match_dup 3)]
10547   "!TARGET_64BIT && TARGET_CMOVE"
10548   [(const_int 0)]
10549   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10551 (define_split
10552   [(set (match_operand:DI 0 "register_operand" "")
10553         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10554                    (match_operand:QI 2 "nonmemory_operand" "")))
10555    (clobber (reg:CC FLAGS_REG))]
10556   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10557                      ? flow2_completed : reload_completed)"
10558   [(const_int 0)]
10559   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10561 (define_insn "x86_shld_1"
10562   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10563         (ior:SI (ashift:SI (match_dup 0)
10564                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10565                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10566                   (minus:QI (const_int 32) (match_dup 2)))))
10567    (clobber (reg:CC FLAGS_REG))]
10568   ""
10569   "@
10570    shld{l}\t{%2, %1, %0|%0, %1, %2}
10571    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10572   [(set_attr "type" "ishift")
10573    (set_attr "prefix_0f" "1")
10574    (set_attr "mode" "SI")
10575    (set_attr "pent_pair" "np")
10576    (set_attr "athlon_decode" "vector")])
10578 (define_expand "x86_shift_adj_1"
10579   [(set (reg:CCZ FLAGS_REG)
10580         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10581                              (const_int 32))
10582                      (const_int 0)))
10583    (set (match_operand:SI 0 "register_operand" "")
10584         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10585                          (match_operand:SI 1 "register_operand" "")
10586                          (match_dup 0)))
10587    (set (match_dup 1)
10588         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10589                          (match_operand:SI 3 "register_operand" "r")
10590                          (match_dup 1)))]
10591   "TARGET_CMOVE"
10592   "")
10594 (define_expand "x86_shift_adj_2"
10595   [(use (match_operand:SI 0 "register_operand" ""))
10596    (use (match_operand:SI 1 "register_operand" ""))
10597    (use (match_operand:QI 2 "register_operand" ""))]
10598   ""
10600   rtx label = gen_label_rtx ();
10601   rtx tmp;
10603   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10605   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10606   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10607   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10608                               gen_rtx_LABEL_REF (VOIDmode, label),
10609                               pc_rtx);
10610   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10611   JUMP_LABEL (tmp) = label;
10613   emit_move_insn (operands[0], operands[1]);
10614   ix86_expand_clear (operands[1]);
10616   emit_label (label);
10617   LABEL_NUSES (label) = 1;
10619   DONE;
10622 (define_expand "ashlsi3"
10623   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10624         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10625                    (match_operand:QI 2 "nonmemory_operand" "")))
10626    (clobber (reg:CC FLAGS_REG))]
10627   ""
10628   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10630 (define_insn "*ashlsi3_1"
10631   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10632         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10633                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10634    (clobber (reg:CC FLAGS_REG))]
10635   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10637   switch (get_attr_type (insn))
10638     {
10639     case TYPE_ALU:
10640       gcc_assert (operands[2] == const1_rtx);
10641       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10642       return "add{l}\t{%0, %0|%0, %0}";
10644     case TYPE_LEA:
10645       return "#";
10647     default:
10648       if (REG_P (operands[2]))
10649         return "sal{l}\t{%b2, %0|%0, %b2}";
10650       else if (operands[2] == const1_rtx
10651                && (TARGET_SHIFT1 || optimize_size))
10652         return "sal{l}\t%0";
10653       else
10654         return "sal{l}\t{%2, %0|%0, %2}";
10655     }
10657   [(set (attr "type")
10658      (cond [(eq_attr "alternative" "1")
10659               (const_string "lea")
10660             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10661                           (const_int 0))
10662                       (match_operand 0 "register_operand" ""))
10663                  (match_operand 2 "const1_operand" ""))
10664               (const_string "alu")
10665            ]
10666            (const_string "ishift")))
10667    (set_attr "mode" "SI")])
10669 ;; Convert lea to the lea pattern to avoid flags dependency.
10670 (define_split
10671   [(set (match_operand 0 "register_operand" "")
10672         (ashift (match_operand 1 "index_register_operand" "")
10673                 (match_operand:QI 2 "const_int_operand" "")))
10674    (clobber (reg:CC FLAGS_REG))]
10675   "reload_completed
10676    && true_regnum (operands[0]) != true_regnum (operands[1])
10677    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10678   [(const_int 0)]
10680   rtx pat;
10681   enum machine_mode mode = GET_MODE (operands[0]);
10683   if (GET_MODE_SIZE (mode) < 4)
10684     operands[0] = gen_lowpart (SImode, operands[0]);
10685   if (mode != Pmode)
10686     operands[1] = gen_lowpart (Pmode, operands[1]);
10687   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10689   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10690   if (Pmode != SImode)
10691     pat = gen_rtx_SUBREG (SImode, pat, 0);
10692   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10693   DONE;
10696 ;; Rare case of shifting RSP is handled by generating move and shift
10697 (define_split
10698   [(set (match_operand 0 "register_operand" "")
10699         (ashift (match_operand 1 "register_operand" "")
10700                 (match_operand:QI 2 "const_int_operand" "")))
10701    (clobber (reg:CC FLAGS_REG))]
10702   "reload_completed
10703    && true_regnum (operands[0]) != true_regnum (operands[1])"
10704   [(const_int 0)]
10706   rtx pat, clob;
10707   emit_move_insn (operands[0], operands[1]);
10708   pat = gen_rtx_SET (VOIDmode, operands[0],
10709                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10710                                      operands[0], operands[2]));
10711   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10712   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10713   DONE;
10716 (define_insn "*ashlsi3_1_zext"
10717   [(set (match_operand:DI 0 "register_operand" "=r,r")
10718         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10719                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10720    (clobber (reg:CC FLAGS_REG))]
10721   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10723   switch (get_attr_type (insn))
10724     {
10725     case TYPE_ALU:
10726       gcc_assert (operands[2] == const1_rtx);
10727       return "add{l}\t{%k0, %k0|%k0, %k0}";
10729     case TYPE_LEA:
10730       return "#";
10732     default:
10733       if (REG_P (operands[2]))
10734         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10735       else if (operands[2] == const1_rtx
10736                && (TARGET_SHIFT1 || optimize_size))
10737         return "sal{l}\t%k0";
10738       else
10739         return "sal{l}\t{%2, %k0|%k0, %2}";
10740     }
10742   [(set (attr "type")
10743      (cond [(eq_attr "alternative" "1")
10744               (const_string "lea")
10745             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10746                      (const_int 0))
10747                  (match_operand 2 "const1_operand" ""))
10748               (const_string "alu")
10749            ]
10750            (const_string "ishift")))
10751    (set_attr "mode" "SI")])
10753 ;; Convert lea to the lea pattern to avoid flags dependency.
10754 (define_split
10755   [(set (match_operand:DI 0 "register_operand" "")
10756         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10757                                 (match_operand:QI 2 "const_int_operand" ""))))
10758    (clobber (reg:CC FLAGS_REG))]
10759   "TARGET_64BIT && reload_completed
10760    && true_regnum (operands[0]) != true_regnum (operands[1])"
10761   [(set (match_dup 0) (zero_extend:DI
10762                         (subreg:SI (mult:SI (match_dup 1)
10763                                             (match_dup 2)) 0)))]
10765   operands[1] = gen_lowpart (Pmode, operands[1]);
10766   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10769 ;; This pattern can't accept a variable shift count, since shifts by
10770 ;; zero don't affect the flags.  We assume that shifts by constant
10771 ;; zero are optimized away.
10772 (define_insn "*ashlsi3_cmp"
10773   [(set (reg FLAGS_REG)
10774         (compare
10775           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10776                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10777           (const_int 0)))
10778    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10779         (ashift:SI (match_dup 1) (match_dup 2)))]
10780   "ix86_match_ccmode (insn, CCGOCmode)
10781    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10782    && (optimize_size
10783        || !TARGET_PARTIAL_FLAG_REG_STALL
10784        || (operands[2] == const1_rtx
10785            && (TARGET_SHIFT1
10786                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10788   switch (get_attr_type (insn))
10789     {
10790     case TYPE_ALU:
10791       gcc_assert (operands[2] == const1_rtx);
10792       return "add{l}\t{%0, %0|%0, %0}";
10794     default:
10795       if (REG_P (operands[2]))
10796         return "sal{l}\t{%b2, %0|%0, %b2}";
10797       else if (operands[2] == const1_rtx
10798                && (TARGET_SHIFT1 || optimize_size))
10799         return "sal{l}\t%0";
10800       else
10801         return "sal{l}\t{%2, %0|%0, %2}";
10802     }
10804   [(set (attr "type")
10805      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10806                           (const_int 0))
10807                       (match_operand 0 "register_operand" ""))
10808                  (match_operand 2 "const1_operand" ""))
10809               (const_string "alu")
10810            ]
10811            (const_string "ishift")))
10812    (set_attr "mode" "SI")])
10814 (define_insn "*ashlsi3_cconly"
10815   [(set (reg FLAGS_REG)
10816         (compare
10817           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10818                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10819           (const_int 0)))
10820    (clobber (match_scratch:SI 0 "=r"))]
10821   "ix86_match_ccmode (insn, CCGOCmode)
10822    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10823    && (optimize_size
10824        || !TARGET_PARTIAL_FLAG_REG_STALL
10825        || (operands[2] == const1_rtx
10826            && (TARGET_SHIFT1
10827                || TARGET_DOUBLE_WITH_ADD)))"
10829   switch (get_attr_type (insn))
10830     {
10831     case TYPE_ALU:
10832       gcc_assert (operands[2] == const1_rtx);
10833       return "add{l}\t{%0, %0|%0, %0}";
10835     default:
10836       if (REG_P (operands[2]))
10837         return "sal{l}\t{%b2, %0|%0, %b2}";
10838       else if (operands[2] == const1_rtx
10839                && (TARGET_SHIFT1 || optimize_size))
10840         return "sal{l}\t%0";
10841       else
10842         return "sal{l}\t{%2, %0|%0, %2}";
10843     }
10845   [(set (attr "type")
10846      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10847                           (const_int 0))
10848                       (match_operand 0 "register_operand" ""))
10849                  (match_operand 2 "const1_operand" ""))
10850               (const_string "alu")
10851            ]
10852            (const_string "ishift")))
10853    (set_attr "mode" "SI")])
10855 (define_insn "*ashlsi3_cmp_zext"
10856   [(set (reg FLAGS_REG)
10857         (compare
10858           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10859                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10860           (const_int 0)))
10861    (set (match_operand:DI 0 "register_operand" "=r")
10862         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10863   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10864    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10865    && (optimize_size
10866        || !TARGET_PARTIAL_FLAG_REG_STALL
10867        || (operands[2] == const1_rtx
10868            && (TARGET_SHIFT1
10869                || TARGET_DOUBLE_WITH_ADD)))"
10871   switch (get_attr_type (insn))
10872     {
10873     case TYPE_ALU:
10874       gcc_assert (operands[2] == const1_rtx);
10875       return "add{l}\t{%k0, %k0|%k0, %k0}";
10877     default:
10878       if (REG_P (operands[2]))
10879         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10880       else if (operands[2] == const1_rtx
10881                && (TARGET_SHIFT1 || optimize_size))
10882         return "sal{l}\t%k0";
10883       else
10884         return "sal{l}\t{%2, %k0|%k0, %2}";
10885     }
10887   [(set (attr "type")
10888      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10889                      (const_int 0))
10890                  (match_operand 2 "const1_operand" ""))
10891               (const_string "alu")
10892            ]
10893            (const_string "ishift")))
10894    (set_attr "mode" "SI")])
10896 (define_expand "ashlhi3"
10897   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10898         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10899                    (match_operand:QI 2 "nonmemory_operand" "")))
10900    (clobber (reg:CC FLAGS_REG))]
10901   "TARGET_HIMODE_MATH"
10902   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10904 (define_insn "*ashlhi3_1_lea"
10905   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10906         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10907                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10908    (clobber (reg:CC FLAGS_REG))]
10909   "!TARGET_PARTIAL_REG_STALL
10910    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10912   switch (get_attr_type (insn))
10913     {
10914     case TYPE_LEA:
10915       return "#";
10916     case TYPE_ALU:
10917       gcc_assert (operands[2] == const1_rtx);
10918       return "add{w}\t{%0, %0|%0, %0}";
10920     default:
10921       if (REG_P (operands[2]))
10922         return "sal{w}\t{%b2, %0|%0, %b2}";
10923       else if (operands[2] == const1_rtx
10924                && (TARGET_SHIFT1 || optimize_size))
10925         return "sal{w}\t%0";
10926       else
10927         return "sal{w}\t{%2, %0|%0, %2}";
10928     }
10930   [(set (attr "type")
10931      (cond [(eq_attr "alternative" "1")
10932               (const_string "lea")
10933             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10934                           (const_int 0))
10935                       (match_operand 0 "register_operand" ""))
10936                  (match_operand 2 "const1_operand" ""))
10937               (const_string "alu")
10938            ]
10939            (const_string "ishift")))
10940    (set_attr "mode" "HI,SI")])
10942 (define_insn "*ashlhi3_1"
10943   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10944         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10945                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10946    (clobber (reg:CC FLAGS_REG))]
10947   "TARGET_PARTIAL_REG_STALL
10948    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10950   switch (get_attr_type (insn))
10951     {
10952     case TYPE_ALU:
10953       gcc_assert (operands[2] == const1_rtx);
10954       return "add{w}\t{%0, %0|%0, %0}";
10956     default:
10957       if (REG_P (operands[2]))
10958         return "sal{w}\t{%b2, %0|%0, %b2}";
10959       else if (operands[2] == const1_rtx
10960                && (TARGET_SHIFT1 || optimize_size))
10961         return "sal{w}\t%0";
10962       else
10963         return "sal{w}\t{%2, %0|%0, %2}";
10964     }
10966   [(set (attr "type")
10967      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10968                           (const_int 0))
10969                       (match_operand 0 "register_operand" ""))
10970                  (match_operand 2 "const1_operand" ""))
10971               (const_string "alu")
10972            ]
10973            (const_string "ishift")))
10974    (set_attr "mode" "HI")])
10976 ;; This pattern can't accept a variable shift count, since shifts by
10977 ;; zero don't affect the flags.  We assume that shifts by constant
10978 ;; zero are optimized away.
10979 (define_insn "*ashlhi3_cmp"
10980   [(set (reg FLAGS_REG)
10981         (compare
10982           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10983                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10984           (const_int 0)))
10985    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10986         (ashift:HI (match_dup 1) (match_dup 2)))]
10987   "ix86_match_ccmode (insn, CCGOCmode)
10988    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10989    && (optimize_size
10990        || !TARGET_PARTIAL_FLAG_REG_STALL
10991        || (operands[2] == const1_rtx
10992            && (TARGET_SHIFT1
10993                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10995   switch (get_attr_type (insn))
10996     {
10997     case TYPE_ALU:
10998       gcc_assert (operands[2] == const1_rtx);
10999       return "add{w}\t{%0, %0|%0, %0}";
11001     default:
11002       if (REG_P (operands[2]))
11003         return "sal{w}\t{%b2, %0|%0, %b2}";
11004       else if (operands[2] == const1_rtx
11005                && (TARGET_SHIFT1 || optimize_size))
11006         return "sal{w}\t%0";
11007       else
11008         return "sal{w}\t{%2, %0|%0, %2}";
11009     }
11011   [(set (attr "type")
11012      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11013                           (const_int 0))
11014                       (match_operand 0 "register_operand" ""))
11015                  (match_operand 2 "const1_operand" ""))
11016               (const_string "alu")
11017            ]
11018            (const_string "ishift")))
11019    (set_attr "mode" "HI")])
11021 (define_insn "*ashlhi3_cconly"
11022   [(set (reg FLAGS_REG)
11023         (compare
11024           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11025                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11026           (const_int 0)))
11027    (clobber (match_scratch:HI 0 "=r"))]
11028   "ix86_match_ccmode (insn, CCGOCmode)
11029    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11030    && (optimize_size
11031        || !TARGET_PARTIAL_FLAG_REG_STALL
11032        || (operands[2] == const1_rtx
11033            && (TARGET_SHIFT1
11034                || TARGET_DOUBLE_WITH_ADD)))"
11036   switch (get_attr_type (insn))
11037     {
11038     case TYPE_ALU:
11039       gcc_assert (operands[2] == const1_rtx);
11040       return "add{w}\t{%0, %0|%0, %0}";
11042     default:
11043       if (REG_P (operands[2]))
11044         return "sal{w}\t{%b2, %0|%0, %b2}";
11045       else if (operands[2] == const1_rtx
11046                && (TARGET_SHIFT1 || optimize_size))
11047         return "sal{w}\t%0";
11048       else
11049         return "sal{w}\t{%2, %0|%0, %2}";
11050     }
11052   [(set (attr "type")
11053      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11054                           (const_int 0))
11055                       (match_operand 0 "register_operand" ""))
11056                  (match_operand 2 "const1_operand" ""))
11057               (const_string "alu")
11058            ]
11059            (const_string "ishift")))
11060    (set_attr "mode" "HI")])
11062 (define_expand "ashlqi3"
11063   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11064         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11065                    (match_operand:QI 2 "nonmemory_operand" "")))
11066    (clobber (reg:CC FLAGS_REG))]
11067   "TARGET_QIMODE_MATH"
11068   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11070 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11072 (define_insn "*ashlqi3_1_lea"
11073   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11074         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11075                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11076    (clobber (reg:CC FLAGS_REG))]
11077   "!TARGET_PARTIAL_REG_STALL
11078    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11080   switch (get_attr_type (insn))
11081     {
11082     case TYPE_LEA:
11083       return "#";
11084     case TYPE_ALU:
11085       gcc_assert (operands[2] == const1_rtx);
11086       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11087         return "add{l}\t{%k0, %k0|%k0, %k0}";
11088       else
11089         return "add{b}\t{%0, %0|%0, %0}";
11091     default:
11092       if (REG_P (operands[2]))
11093         {
11094           if (get_attr_mode (insn) == MODE_SI)
11095             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11096           else
11097             return "sal{b}\t{%b2, %0|%0, %b2}";
11098         }
11099       else if (operands[2] == const1_rtx
11100                && (TARGET_SHIFT1 || optimize_size))
11101         {
11102           if (get_attr_mode (insn) == MODE_SI)
11103             return "sal{l}\t%0";
11104           else
11105             return "sal{b}\t%0";
11106         }
11107       else
11108         {
11109           if (get_attr_mode (insn) == MODE_SI)
11110             return "sal{l}\t{%2, %k0|%k0, %2}";
11111           else
11112             return "sal{b}\t{%2, %0|%0, %2}";
11113         }
11114     }
11116   [(set (attr "type")
11117      (cond [(eq_attr "alternative" "2")
11118               (const_string "lea")
11119             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11120                           (const_int 0))
11121                       (match_operand 0 "register_operand" ""))
11122                  (match_operand 2 "const1_operand" ""))
11123               (const_string "alu")
11124            ]
11125            (const_string "ishift")))
11126    (set_attr "mode" "QI,SI,SI")])
11128 (define_insn "*ashlqi3_1"
11129   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11130         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11131                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11132    (clobber (reg:CC FLAGS_REG))]
11133   "TARGET_PARTIAL_REG_STALL
11134    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11136   switch (get_attr_type (insn))
11137     {
11138     case TYPE_ALU:
11139       gcc_assert (operands[2] == const1_rtx);
11140       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11141         return "add{l}\t{%k0, %k0|%k0, %k0}";
11142       else
11143         return "add{b}\t{%0, %0|%0, %0}";
11145     default:
11146       if (REG_P (operands[2]))
11147         {
11148           if (get_attr_mode (insn) == MODE_SI)
11149             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11150           else
11151             return "sal{b}\t{%b2, %0|%0, %b2}";
11152         }
11153       else if (operands[2] == const1_rtx
11154                && (TARGET_SHIFT1 || optimize_size))
11155         {
11156           if (get_attr_mode (insn) == MODE_SI)
11157             return "sal{l}\t%0";
11158           else
11159             return "sal{b}\t%0";
11160         }
11161       else
11162         {
11163           if (get_attr_mode (insn) == MODE_SI)
11164             return "sal{l}\t{%2, %k0|%k0, %2}";
11165           else
11166             return "sal{b}\t{%2, %0|%0, %2}";
11167         }
11168     }
11170   [(set (attr "type")
11171      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11172                           (const_int 0))
11173                       (match_operand 0 "register_operand" ""))
11174                  (match_operand 2 "const1_operand" ""))
11175               (const_string "alu")
11176            ]
11177            (const_string "ishift")))
11178    (set_attr "mode" "QI,SI")])
11180 ;; This pattern can't accept a variable shift count, since shifts by
11181 ;; zero don't affect the flags.  We assume that shifts by constant
11182 ;; zero are optimized away.
11183 (define_insn "*ashlqi3_cmp"
11184   [(set (reg FLAGS_REG)
11185         (compare
11186           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11187                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11188           (const_int 0)))
11189    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11190         (ashift:QI (match_dup 1) (match_dup 2)))]
11191   "ix86_match_ccmode (insn, CCGOCmode)
11192    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11193    && (optimize_size
11194        || !TARGET_PARTIAL_FLAG_REG_STALL
11195        || (operands[2] == const1_rtx
11196            && (TARGET_SHIFT1
11197                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11199   switch (get_attr_type (insn))
11200     {
11201     case TYPE_ALU:
11202       gcc_assert (operands[2] == const1_rtx);
11203       return "add{b}\t{%0, %0|%0, %0}";
11205     default:
11206       if (REG_P (operands[2]))
11207         return "sal{b}\t{%b2, %0|%0, %b2}";
11208       else if (operands[2] == const1_rtx
11209                && (TARGET_SHIFT1 || optimize_size))
11210         return "sal{b}\t%0";
11211       else
11212         return "sal{b}\t{%2, %0|%0, %2}";
11213     }
11215   [(set (attr "type")
11216      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11217                           (const_int 0))
11218                       (match_operand 0 "register_operand" ""))
11219                  (match_operand 2 "const1_operand" ""))
11220               (const_string "alu")
11221            ]
11222            (const_string "ishift")))
11223    (set_attr "mode" "QI")])
11225 (define_insn "*ashlqi3_cconly"
11226   [(set (reg FLAGS_REG)
11227         (compare
11228           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11229                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11230           (const_int 0)))
11231    (clobber (match_scratch:QI 0 "=q"))]
11232   "ix86_match_ccmode (insn, CCGOCmode)
11233    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11234    && (optimize_size
11235        || !TARGET_PARTIAL_FLAG_REG_STALL
11236        || (operands[2] == const1_rtx
11237            && (TARGET_SHIFT1
11238                || TARGET_DOUBLE_WITH_ADD)))"
11240   switch (get_attr_type (insn))
11241     {
11242     case TYPE_ALU:
11243       gcc_assert (operands[2] == const1_rtx);
11244       return "add{b}\t{%0, %0|%0, %0}";
11246     default:
11247       if (REG_P (operands[2]))
11248         return "sal{b}\t{%b2, %0|%0, %b2}";
11249       else if (operands[2] == const1_rtx
11250                && (TARGET_SHIFT1 || optimize_size))
11251         return "sal{b}\t%0";
11252       else
11253         return "sal{b}\t{%2, %0|%0, %2}";
11254     }
11256   [(set (attr "type")
11257      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11258                           (const_int 0))
11259                       (match_operand 0 "register_operand" ""))
11260                  (match_operand 2 "const1_operand" ""))
11261               (const_string "alu")
11262            ]
11263            (const_string "ishift")))
11264    (set_attr "mode" "QI")])
11266 ;; See comment above `ashldi3' about how this works.
11268 (define_expand "ashrti3"
11269   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11270                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11271                                 (match_operand:QI 2 "nonmemory_operand" "")))
11272               (clobber (reg:CC FLAGS_REG))])]
11273   "TARGET_64BIT"
11275   if (! immediate_operand (operands[2], QImode))
11276     {
11277       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11278       DONE;
11279     }
11280   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11281   DONE;
11284 (define_insn "ashrti3_1"
11285   [(set (match_operand:TI 0 "register_operand" "=r")
11286         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11287                      (match_operand:QI 2 "register_operand" "c")))
11288    (clobber (match_scratch:DI 3 "=&r"))
11289    (clobber (reg:CC FLAGS_REG))]
11290   "TARGET_64BIT"
11291   "#"
11292   [(set_attr "type" "multi")])
11294 (define_insn "*ashrti3_2"
11295   [(set (match_operand:TI 0 "register_operand" "=r")
11296         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11297                      (match_operand:QI 2 "immediate_operand" "O")))
11298    (clobber (reg:CC FLAGS_REG))]
11299   "TARGET_64BIT"
11300   "#"
11301   [(set_attr "type" "multi")])
11303 (define_split
11304   [(set (match_operand:TI 0 "register_operand" "")
11305         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11306                      (match_operand:QI 2 "register_operand" "")))
11307    (clobber (match_scratch:DI 3 ""))
11308    (clobber (reg:CC FLAGS_REG))]
11309   "TARGET_64BIT && reload_completed"
11310   [(const_int 0)]
11311   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11313 (define_split
11314   [(set (match_operand:TI 0 "register_operand" "")
11315         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11316                      (match_operand:QI 2 "immediate_operand" "")))
11317    (clobber (reg:CC FLAGS_REG))]
11318   "TARGET_64BIT && reload_completed"
11319   [(const_int 0)]
11320   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11322 (define_insn "x86_64_shrd"
11323   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11324         (ior:DI (ashiftrt:DI (match_dup 0)
11325                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11326                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11327                   (minus:QI (const_int 64) (match_dup 2)))))
11328    (clobber (reg:CC FLAGS_REG))]
11329   "TARGET_64BIT"
11330   "@
11331    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11332    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11333   [(set_attr "type" "ishift")
11334    (set_attr "prefix_0f" "1")
11335    (set_attr "mode" "DI")
11336    (set_attr "athlon_decode" "vector")])
11338 (define_expand "ashrdi3"
11339   [(set (match_operand:DI 0 "shiftdi_operand" "")
11340         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11341                      (match_operand:QI 2 "nonmemory_operand" "")))]
11342   ""
11343   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11345 (define_insn "*ashrdi3_63_rex64"
11346   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11347         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11348                      (match_operand:DI 2 "const_int_operand" "i,i")))
11349    (clobber (reg:CC FLAGS_REG))]
11350   "TARGET_64BIT && INTVAL (operands[2]) == 63
11351    && (TARGET_USE_CLTD || optimize_size)
11352    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11353   "@
11354    {cqto|cqo}
11355    sar{q}\t{%2, %0|%0, %2}"
11356   [(set_attr "type" "imovx,ishift")
11357    (set_attr "prefix_0f" "0,*")
11358    (set_attr "length_immediate" "0,*")
11359    (set_attr "modrm" "0,1")
11360    (set_attr "mode" "DI")])
11362 (define_insn "*ashrdi3_1_one_bit_rex64"
11363   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11364         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11365                      (match_operand:QI 2 "const1_operand" "")))
11366    (clobber (reg:CC FLAGS_REG))]
11367   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11368    && (TARGET_SHIFT1 || optimize_size)"
11369   "sar{q}\t%0"
11370   [(set_attr "type" "ishift")
11371    (set (attr "length")
11372      (if_then_else (match_operand:DI 0 "register_operand" "")
11373         (const_string "2")
11374         (const_string "*")))])
11376 (define_insn "*ashrdi3_1_rex64"
11377   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11378         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11379                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11380    (clobber (reg:CC FLAGS_REG))]
11381   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11382   "@
11383    sar{q}\t{%2, %0|%0, %2}
11384    sar{q}\t{%b2, %0|%0, %b2}"
11385   [(set_attr "type" "ishift")
11386    (set_attr "mode" "DI")])
11388 ;; This pattern can't accept a variable shift count, since shifts by
11389 ;; zero don't affect the flags.  We assume that shifts by constant
11390 ;; zero are optimized away.
11391 (define_insn "*ashrdi3_one_bit_cmp_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    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11398         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11399   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11400    && (TARGET_SHIFT1 || optimize_size)
11401    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11402   "sar{q}\t%0"
11403   [(set_attr "type" "ishift")
11404    (set (attr "length")
11405      (if_then_else (match_operand:DI 0 "register_operand" "")
11406         (const_string "2")
11407         (const_string "*")))])
11409 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11410   [(set (reg FLAGS_REG)
11411         (compare
11412           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11413                        (match_operand:QI 2 "const1_operand" ""))
11414           (const_int 0)))
11415    (clobber (match_scratch:DI 0 "=r"))]
11416   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11417    && (TARGET_SHIFT1 || optimize_size)
11418    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11419   "sar{q}\t%0"
11420   [(set_attr "type" "ishift")
11421    (set_attr "length" "2")])
11423 ;; This pattern can't accept a variable shift count, since shifts by
11424 ;; zero don't affect the flags.  We assume that shifts by constant
11425 ;; zero are optimized away.
11426 (define_insn "*ashrdi3_cmp_rex64"
11427   [(set (reg FLAGS_REG)
11428         (compare
11429           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11430                        (match_operand:QI 2 "const_int_operand" "n"))
11431           (const_int 0)))
11432    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11433         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11434   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11435    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11436    && (optimize_size
11437        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11438   "sar{q}\t{%2, %0|%0, %2}"
11439   [(set_attr "type" "ishift")
11440    (set_attr "mode" "DI")])
11442 (define_insn "*ashrdi3_cconly_rex64"
11443   [(set (reg FLAGS_REG)
11444         (compare
11445           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11446                        (match_operand:QI 2 "const_int_operand" "n"))
11447           (const_int 0)))
11448    (clobber (match_scratch:DI 0 "=r"))]
11449   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11450    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11451    && (optimize_size
11452        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11453   "sar{q}\t{%2, %0|%0, %2}"
11454   [(set_attr "type" "ishift")
11455    (set_attr "mode" "DI")])
11457 (define_insn "*ashrdi3_1"
11458   [(set (match_operand:DI 0 "register_operand" "=r")
11459         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11460                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11461    (clobber (reg:CC FLAGS_REG))]
11462   "!TARGET_64BIT"
11463   "#"
11464   [(set_attr "type" "multi")])
11466 ;; By default we don't ask for a scratch register, because when DImode
11467 ;; values are manipulated, registers are already at a premium.  But if
11468 ;; we have one handy, we won't turn it away.
11469 (define_peephole2
11470   [(match_scratch:SI 3 "r")
11471    (parallel [(set (match_operand:DI 0 "register_operand" "")
11472                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11473                                 (match_operand:QI 2 "nonmemory_operand" "")))
11474               (clobber (reg:CC FLAGS_REG))])
11475    (match_dup 3)]
11476   "!TARGET_64BIT && TARGET_CMOVE"
11477   [(const_int 0)]
11478   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11480 (define_split
11481   [(set (match_operand:DI 0 "register_operand" "")
11482         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11483                      (match_operand:QI 2 "nonmemory_operand" "")))
11484    (clobber (reg:CC FLAGS_REG))]
11485   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11486                      ? flow2_completed : reload_completed)"
11487   [(const_int 0)]
11488   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11490 (define_insn "x86_shrd_1"
11491   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11492         (ior:SI (ashiftrt:SI (match_dup 0)
11493                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11494                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11495                   (minus:QI (const_int 32) (match_dup 2)))))
11496    (clobber (reg:CC FLAGS_REG))]
11497   ""
11498   "@
11499    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11500    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11501   [(set_attr "type" "ishift")
11502    (set_attr "prefix_0f" "1")
11503    (set_attr "pent_pair" "np")
11504    (set_attr "mode" "SI")])
11506 (define_expand "x86_shift_adj_3"
11507   [(use (match_operand:SI 0 "register_operand" ""))
11508    (use (match_operand:SI 1 "register_operand" ""))
11509    (use (match_operand:QI 2 "register_operand" ""))]
11510   ""
11512   rtx label = gen_label_rtx ();
11513   rtx tmp;
11515   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11517   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11518   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11519   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11520                               gen_rtx_LABEL_REF (VOIDmode, label),
11521                               pc_rtx);
11522   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11523   JUMP_LABEL (tmp) = label;
11525   emit_move_insn (operands[0], operands[1]);
11526   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11528   emit_label (label);
11529   LABEL_NUSES (label) = 1;
11531   DONE;
11534 (define_insn "ashrsi3_31"
11535   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11536         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11537                      (match_operand:SI 2 "const_int_operand" "i,i")))
11538    (clobber (reg:CC FLAGS_REG))]
11539   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11540    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11541   "@
11542    {cltd|cdq}
11543    sar{l}\t{%2, %0|%0, %2}"
11544   [(set_attr "type" "imovx,ishift")
11545    (set_attr "prefix_0f" "0,*")
11546    (set_attr "length_immediate" "0,*")
11547    (set_attr "modrm" "0,1")
11548    (set_attr "mode" "SI")])
11550 (define_insn "*ashrsi3_31_zext"
11551   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11552         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11553                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11554    (clobber (reg:CC FLAGS_REG))]
11555   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11556    && INTVAL (operands[2]) == 31
11557    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558   "@
11559    {cltd|cdq}
11560    sar{l}\t{%2, %k0|%k0, %2}"
11561   [(set_attr "type" "imovx,ishift")
11562    (set_attr "prefix_0f" "0,*")
11563    (set_attr "length_immediate" "0,*")
11564    (set_attr "modrm" "0,1")
11565    (set_attr "mode" "SI")])
11567 (define_expand "ashrsi3"
11568   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11569         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11570                      (match_operand:QI 2 "nonmemory_operand" "")))
11571    (clobber (reg:CC FLAGS_REG))]
11572   ""
11573   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11575 (define_insn "*ashrsi3_1_one_bit"
11576   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11577         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11578                      (match_operand:QI 2 "const1_operand" "")))
11579    (clobber (reg:CC FLAGS_REG))]
11580   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11581    && (TARGET_SHIFT1 || optimize_size)"
11582   "sar{l}\t%0"
11583   [(set_attr "type" "ishift")
11584    (set (attr "length")
11585      (if_then_else (match_operand:SI 0 "register_operand" "")
11586         (const_string "2")
11587         (const_string "*")))])
11589 (define_insn "*ashrsi3_1_one_bit_zext"
11590   [(set (match_operand:DI 0 "register_operand" "=r")
11591         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11592                                      (match_operand:QI 2 "const1_operand" ""))))
11593    (clobber (reg:CC FLAGS_REG))]
11594   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11595    && (TARGET_SHIFT1 || optimize_size)"
11596   "sar{l}\t%k0"
11597   [(set_attr "type" "ishift")
11598    (set_attr "length" "2")])
11600 (define_insn "*ashrsi3_1"
11601   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11602         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11603                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11604    (clobber (reg:CC FLAGS_REG))]
11605   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11606   "@
11607    sar{l}\t{%2, %0|%0, %2}
11608    sar{l}\t{%b2, %0|%0, %b2}"
11609   [(set_attr "type" "ishift")
11610    (set_attr "mode" "SI")])
11612 (define_insn "*ashrsi3_1_zext"
11613   [(set (match_operand:DI 0 "register_operand" "=r,r")
11614         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11615                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11616    (clobber (reg:CC FLAGS_REG))]
11617   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11618   "@
11619    sar{l}\t{%2, %k0|%k0, %2}
11620    sar{l}\t{%b2, %k0|%k0, %b2}"
11621   [(set_attr "type" "ishift")
11622    (set_attr "mode" "SI")])
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags.  We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrsi3_one_bit_cmp"
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    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11634         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11635   "ix86_match_ccmode (insn, CCGOCmode)
11636    && (TARGET_SHIFT1 || optimize_size)
11637    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11638   "sar{l}\t%0"
11639   [(set_attr "type" "ishift")
11640    (set (attr "length")
11641      (if_then_else (match_operand:SI 0 "register_operand" "")
11642         (const_string "2")
11643         (const_string "*")))])
11645 (define_insn "*ashrsi3_one_bit_cconly"
11646   [(set (reg FLAGS_REG)
11647         (compare
11648           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11649                        (match_operand:QI 2 "const1_operand" ""))
11650           (const_int 0)))
11651    (clobber (match_scratch:SI 0 "=r"))]
11652   "ix86_match_ccmode (insn, CCGOCmode)
11653    && (TARGET_SHIFT1 || optimize_size)
11654    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11655   "sar{l}\t%0"
11656   [(set_attr "type" "ishift")
11657    (set_attr "length" "2")])
11659 (define_insn "*ashrsi3_one_bit_cmp_zext"
11660   [(set (reg FLAGS_REG)
11661         (compare
11662           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11663                        (match_operand:QI 2 "const1_operand" ""))
11664           (const_int 0)))
11665    (set (match_operand:DI 0 "register_operand" "=r")
11666         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11667   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11668    && (TARGET_SHIFT1 || optimize_size)
11669    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11670   "sar{l}\t%k0"
11671   [(set_attr "type" "ishift")
11672    (set_attr "length" "2")])
11674 ;; This pattern can't accept a variable shift count, since shifts by
11675 ;; zero don't affect the flags.  We assume that shifts by constant
11676 ;; zero are optimized away.
11677 (define_insn "*ashrsi3_cmp"
11678   [(set (reg FLAGS_REG)
11679         (compare
11680           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11681                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11682           (const_int 0)))
11683    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11684         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11685   "ix86_match_ccmode (insn, CCGOCmode)
11686    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11687    && (optimize_size
11688        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11689   "sar{l}\t{%2, %0|%0, %2}"
11690   [(set_attr "type" "ishift")
11691    (set_attr "mode" "SI")])
11693 (define_insn "*ashrsi3_cconly"
11694   [(set (reg FLAGS_REG)
11695         (compare
11696           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11697                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11698           (const_int 0)))
11699    (clobber (match_scratch:SI 0 "=r"))]
11700   "ix86_match_ccmode (insn, CCGOCmode)
11701    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11702    && (optimize_size
11703        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11704   "sar{l}\t{%2, %0|%0, %2}"
11705   [(set_attr "type" "ishift")
11706    (set_attr "mode" "SI")])
11708 (define_insn "*ashrsi3_cmp_zext"
11709   [(set (reg FLAGS_REG)
11710         (compare
11711           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11712                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11713           (const_int 0)))
11714    (set (match_operand:DI 0 "register_operand" "=r")
11715         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11716   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11717    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11718    && (optimize_size
11719        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11720   "sar{l}\t{%2, %k0|%k0, %2}"
11721   [(set_attr "type" "ishift")
11722    (set_attr "mode" "SI")])
11724 (define_expand "ashrhi3"
11725   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11726         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11727                      (match_operand:QI 2 "nonmemory_operand" "")))
11728    (clobber (reg:CC FLAGS_REG))]
11729   "TARGET_HIMODE_MATH"
11730   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11732 (define_insn "*ashrhi3_1_one_bit"
11733   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11734         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11735                      (match_operand:QI 2 "const1_operand" "")))
11736    (clobber (reg:CC FLAGS_REG))]
11737   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11738    && (TARGET_SHIFT1 || optimize_size)"
11739   "sar{w}\t%0"
11740   [(set_attr "type" "ishift")
11741    (set (attr "length")
11742      (if_then_else (match_operand 0 "register_operand" "")
11743         (const_string "2")
11744         (const_string "*")))])
11746 (define_insn "*ashrhi3_1"
11747   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11748         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11749                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11750    (clobber (reg:CC FLAGS_REG))]
11751   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11752   "@
11753    sar{w}\t{%2, %0|%0, %2}
11754    sar{w}\t{%b2, %0|%0, %b2}"
11755   [(set_attr "type" "ishift")
11756    (set_attr "mode" "HI")])
11758 ;; This pattern can't accept a variable shift count, since shifts by
11759 ;; zero don't affect the flags.  We assume that shifts by constant
11760 ;; zero are optimized away.
11761 (define_insn "*ashrhi3_one_bit_cmp"
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    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11768         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11769   "ix86_match_ccmode (insn, CCGOCmode)
11770    && (TARGET_SHIFT1 || optimize_size)
11771    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11772   "sar{w}\t%0"
11773   [(set_attr "type" "ishift")
11774    (set (attr "length")
11775      (if_then_else (match_operand 0 "register_operand" "")
11776         (const_string "2")
11777         (const_string "*")))])
11779 (define_insn "*ashrhi3_one_bit_cconly"
11780   [(set (reg FLAGS_REG)
11781         (compare
11782           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11783                        (match_operand:QI 2 "const1_operand" ""))
11784           (const_int 0)))
11785    (clobber (match_scratch:HI 0 "=r"))]
11786   "ix86_match_ccmode (insn, CCGOCmode)
11787    && (TARGET_SHIFT1 || optimize_size)
11788    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11789   "sar{w}\t%0"
11790   [(set_attr "type" "ishift")
11791    (set_attr "length" "2")])
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags.  We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashrhi3_cmp"
11797   [(set (reg FLAGS_REG)
11798         (compare
11799           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11800                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11801           (const_int 0)))
11802    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11803         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11804   "ix86_match_ccmode (insn, CCGOCmode)
11805    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11806    && (optimize_size
11807        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11808   "sar{w}\t{%2, %0|%0, %2}"
11809   [(set_attr "type" "ishift")
11810    (set_attr "mode" "HI")])
11812 (define_insn "*ashrhi3_cconly"
11813   [(set (reg FLAGS_REG)
11814         (compare
11815           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11816                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11817           (const_int 0)))
11818    (clobber (match_scratch:HI 0 "=r"))]
11819   "ix86_match_ccmode (insn, CCGOCmode)
11820    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11821    && (optimize_size
11822        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11823   "sar{w}\t{%2, %0|%0, %2}"
11824   [(set_attr "type" "ishift")
11825    (set_attr "mode" "HI")])
11827 (define_expand "ashrqi3"
11828   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11829         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11830                      (match_operand:QI 2 "nonmemory_operand" "")))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "TARGET_QIMODE_MATH"
11833   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11835 (define_insn "*ashrqi3_1_one_bit"
11836   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11837         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11838                      (match_operand:QI 2 "const1_operand" "")))
11839    (clobber (reg:CC FLAGS_REG))]
11840   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11841    && (TARGET_SHIFT1 || optimize_size)"
11842   "sar{b}\t%0"
11843   [(set_attr "type" "ishift")
11844    (set (attr "length")
11845      (if_then_else (match_operand 0 "register_operand" "")
11846         (const_string "2")
11847         (const_string "*")))])
11849 (define_insn "*ashrqi3_1_one_bit_slp"
11850   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11851         (ashiftrt:QI (match_dup 0)
11852                      (match_operand:QI 1 "const1_operand" "")))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11855    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11856    && (TARGET_SHIFT1 || optimize_size)"
11857   "sar{b}\t%0"
11858   [(set_attr "type" "ishift1")
11859    (set (attr "length")
11860      (if_then_else (match_operand 0 "register_operand" "")
11861         (const_string "2")
11862         (const_string "*")))])
11864 (define_insn "*ashrqi3_1"
11865   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11866         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11867                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11868    (clobber (reg:CC FLAGS_REG))]
11869   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11870   "@
11871    sar{b}\t{%2, %0|%0, %2}
11872    sar{b}\t{%b2, %0|%0, %b2}"
11873   [(set_attr "type" "ishift")
11874    (set_attr "mode" "QI")])
11876 (define_insn "*ashrqi3_1_slp"
11877   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11878         (ashiftrt:QI (match_dup 0)
11879                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11882    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11883   "@
11884    sar{b}\t{%1, %0|%0, %1}
11885    sar{b}\t{%b1, %0|%0, %b1}"
11886   [(set_attr "type" "ishift1")
11887    (set_attr "mode" "QI")])
11889 ;; This pattern can't accept a variable shift count, since shifts by
11890 ;; zero don't affect the flags.  We assume that shifts by constant
11891 ;; zero are optimized away.
11892 (define_insn "*ashrqi3_one_bit_cmp"
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    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11899         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11900   "ix86_match_ccmode (insn, CCGOCmode)
11901    && (TARGET_SHIFT1 || optimize_size)
11902    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11903   "sar{b}\t%0"
11904   [(set_attr "type" "ishift")
11905    (set (attr "length")
11906      (if_then_else (match_operand 0 "register_operand" "")
11907         (const_string "2")
11908         (const_string "*")))])
11910 (define_insn "*ashrqi3_one_bit_cconly"
11911   [(set (reg FLAGS_REG)
11912         (compare
11913           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11914                        (match_operand:QI 2 "const1_operand" "I"))
11915           (const_int 0)))
11916    (clobber (match_scratch:QI 0 "=q"))]
11917   "ix86_match_ccmode (insn, CCGOCmode)
11918    && (TARGET_SHIFT1 || optimize_size)
11919    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11920   "sar{b}\t%0"
11921   [(set_attr "type" "ishift")
11922    (set_attr "length" "2")])
11924 ;; This pattern can't accept a variable shift count, since shifts by
11925 ;; zero don't affect the flags.  We assume that shifts by constant
11926 ;; zero are optimized away.
11927 (define_insn "*ashrqi3_cmp"
11928   [(set (reg FLAGS_REG)
11929         (compare
11930           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11931                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11932           (const_int 0)))
11933    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11934         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11935   "ix86_match_ccmode (insn, CCGOCmode)
11936    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11937    && (optimize_size
11938        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11939   "sar{b}\t{%2, %0|%0, %2}"
11940   [(set_attr "type" "ishift")
11941    (set_attr "mode" "QI")])
11943 (define_insn "*ashrqi3_cconly"
11944   [(set (reg FLAGS_REG)
11945         (compare
11946           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11947                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11948           (const_int 0)))
11949    (clobber (match_scratch:QI 0 "=q"))]
11950   "ix86_match_ccmode (insn, CCGOCmode)
11951    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11952    && (optimize_size
11953        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11954   "sar{b}\t{%2, %0|%0, %2}"
11955   [(set_attr "type" "ishift")
11956    (set_attr "mode" "QI")])
11959 ;; Logical shift instructions
11961 ;; See comment above `ashldi3' about how this works.
11963 (define_expand "lshrti3"
11964   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11965                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11966                                 (match_operand:QI 2 "nonmemory_operand" "")))
11967               (clobber (reg:CC FLAGS_REG))])]
11968   "TARGET_64BIT"
11970   if (! immediate_operand (operands[2], QImode))
11971     {
11972       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11973       DONE;
11974     }
11975   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11976   DONE;
11979 (define_insn "lshrti3_1"
11980   [(set (match_operand:TI 0 "register_operand" "=r")
11981         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11982                      (match_operand:QI 2 "register_operand" "c")))
11983    (clobber (match_scratch:DI 3 "=&r"))
11984    (clobber (reg:CC FLAGS_REG))]
11985   "TARGET_64BIT"
11986   "#"
11987   [(set_attr "type" "multi")])
11989 (define_insn "*lshrti3_2"
11990   [(set (match_operand:TI 0 "register_operand" "=r")
11991         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11992                      (match_operand:QI 2 "immediate_operand" "O")))
11993    (clobber (reg:CC FLAGS_REG))]
11994   "TARGET_64BIT"
11995   "#"
11996   [(set_attr "type" "multi")])
11998 (define_split
11999   [(set (match_operand:TI 0 "register_operand" "")
12000         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12001                      (match_operand:QI 2 "register_operand" "")))
12002    (clobber (match_scratch:DI 3 ""))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "TARGET_64BIT && reload_completed"
12005   [(const_int 0)]
12006   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12008 (define_split
12009   [(set (match_operand:TI 0 "register_operand" "")
12010         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12011                      (match_operand:QI 2 "immediate_operand" "")))
12012    (clobber (reg:CC FLAGS_REG))]
12013   "TARGET_64BIT && reload_completed"
12014   [(const_int 0)]
12015   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12017 (define_expand "lshrdi3"
12018   [(set (match_operand:DI 0 "shiftdi_operand" "")
12019         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12020                      (match_operand:QI 2 "nonmemory_operand" "")))]
12021   ""
12022   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12024 (define_insn "*lshrdi3_1_one_bit_rex64"
12025   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12026         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12027                      (match_operand:QI 2 "const1_operand" "")))
12028    (clobber (reg:CC FLAGS_REG))]
12029   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12030    && (TARGET_SHIFT1 || optimize_size)"
12031   "shr{q}\t%0"
12032   [(set_attr "type" "ishift")
12033    (set (attr "length")
12034      (if_then_else (match_operand:DI 0 "register_operand" "")
12035         (const_string "2")
12036         (const_string "*")))])
12038 (define_insn "*lshrdi3_1_rex64"
12039   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12040         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12041                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12042    (clobber (reg:CC FLAGS_REG))]
12043   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12044   "@
12045    shr{q}\t{%2, %0|%0, %2}
12046    shr{q}\t{%b2, %0|%0, %b2}"
12047   [(set_attr "type" "ishift")
12048    (set_attr "mode" "DI")])
12050 ;; This pattern can't accept a variable shift count, since shifts by
12051 ;; zero don't affect the flags.  We assume that shifts by constant
12052 ;; zero are optimized away.
12053 (define_insn "*lshrdi3_cmp_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    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12060         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12061   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12062    && (TARGET_SHIFT1 || optimize_size)
12063    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12064   "shr{q}\t%0"
12065   [(set_attr "type" "ishift")
12066    (set (attr "length")
12067      (if_then_else (match_operand:DI 0 "register_operand" "")
12068         (const_string "2")
12069         (const_string "*")))])
12071 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12072   [(set (reg FLAGS_REG)
12073         (compare
12074           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12075                        (match_operand:QI 2 "const1_operand" ""))
12076           (const_int 0)))
12077    (clobber (match_scratch:DI 0 "=r"))]
12078   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12079    && (TARGET_SHIFT1 || optimize_size)
12080    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12081   "shr{q}\t%0"
12082   [(set_attr "type" "ishift")
12083    (set_attr "length" "2")])
12085 ;; This pattern can't accept a variable shift count, since shifts by
12086 ;; zero don't affect the flags.  We assume that shifts by constant
12087 ;; zero are optimized away.
12088 (define_insn "*lshrdi3_cmp_rex64"
12089   [(set (reg FLAGS_REG)
12090         (compare
12091           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12092                        (match_operand:QI 2 "const_int_operand" "e"))
12093           (const_int 0)))
12094    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12095         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12096   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12097    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12098    && (optimize_size
12099        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12100   "shr{q}\t{%2, %0|%0, %2}"
12101   [(set_attr "type" "ishift")
12102    (set_attr "mode" "DI")])
12104 (define_insn "*lshrdi3_cconly_rex64"
12105   [(set (reg FLAGS_REG)
12106         (compare
12107           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12108                        (match_operand:QI 2 "const_int_operand" "e"))
12109           (const_int 0)))
12110    (clobber (match_scratch:DI 0 "=r"))]
12111   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12112    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12113    && (optimize_size
12114        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12115   "shr{q}\t{%2, %0|%0, %2}"
12116   [(set_attr "type" "ishift")
12117    (set_attr "mode" "DI")])
12119 (define_insn "*lshrdi3_1"
12120   [(set (match_operand:DI 0 "register_operand" "=r")
12121         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12122                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12123    (clobber (reg:CC FLAGS_REG))]
12124   "!TARGET_64BIT"
12125   "#"
12126   [(set_attr "type" "multi")])
12128 ;; By default we don't ask for a scratch register, because when DImode
12129 ;; values are manipulated, registers are already at a premium.  But if
12130 ;; we have one handy, we won't turn it away.
12131 (define_peephole2
12132   [(match_scratch:SI 3 "r")
12133    (parallel [(set (match_operand:DI 0 "register_operand" "")
12134                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12135                                 (match_operand:QI 2 "nonmemory_operand" "")))
12136               (clobber (reg:CC FLAGS_REG))])
12137    (match_dup 3)]
12138   "!TARGET_64BIT && TARGET_CMOVE"
12139   [(const_int 0)]
12140   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12142 (define_split
12143   [(set (match_operand:DI 0 "register_operand" "")
12144         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12145                      (match_operand:QI 2 "nonmemory_operand" "")))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12148                      ? flow2_completed : reload_completed)"
12149   [(const_int 0)]
12150   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12152 (define_expand "lshrsi3"
12153   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12154         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12155                      (match_operand:QI 2 "nonmemory_operand" "")))
12156    (clobber (reg:CC FLAGS_REG))]
12157   ""
12158   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12160 (define_insn "*lshrsi3_1_one_bit"
12161   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12162         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12163                      (match_operand:QI 2 "const1_operand" "")))
12164    (clobber (reg:CC FLAGS_REG))]
12165   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12166    && (TARGET_SHIFT1 || optimize_size)"
12167   "shr{l}\t%0"
12168   [(set_attr "type" "ishift")
12169    (set (attr "length")
12170      (if_then_else (match_operand:SI 0 "register_operand" "")
12171         (const_string "2")
12172         (const_string "*")))])
12174 (define_insn "*lshrsi3_1_one_bit_zext"
12175   [(set (match_operand:DI 0 "register_operand" "=r")
12176         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12177                      (match_operand:QI 2 "const1_operand" "")))
12178    (clobber (reg:CC FLAGS_REG))]
12179   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12180    && (TARGET_SHIFT1 || optimize_size)"
12181   "shr{l}\t%k0"
12182   [(set_attr "type" "ishift")
12183    (set_attr "length" "2")])
12185 (define_insn "*lshrsi3_1"
12186   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12187         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12188                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12189    (clobber (reg:CC FLAGS_REG))]
12190   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12191   "@
12192    shr{l}\t{%2, %0|%0, %2}
12193    shr{l}\t{%b2, %0|%0, %b2}"
12194   [(set_attr "type" "ishift")
12195    (set_attr "mode" "SI")])
12197 (define_insn "*lshrsi3_1_zext"
12198   [(set (match_operand:DI 0 "register_operand" "=r,r")
12199         (zero_extend:DI
12200           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12201                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12202    (clobber (reg:CC FLAGS_REG))]
12203   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12204   "@
12205    shr{l}\t{%2, %k0|%k0, %2}
12206    shr{l}\t{%b2, %k0|%k0, %b2}"
12207   [(set_attr "type" "ishift")
12208    (set_attr "mode" "SI")])
12210 ;; This pattern can't accept a variable shift count, since shifts by
12211 ;; zero don't affect the flags.  We assume that shifts by constant
12212 ;; zero are optimized away.
12213 (define_insn "*lshrsi3_one_bit_cmp"
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    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12220         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12221   "ix86_match_ccmode (insn, CCGOCmode)
12222    && (TARGET_SHIFT1 || optimize_size)
12223    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12224   "shr{l}\t%0"
12225   [(set_attr "type" "ishift")
12226    (set (attr "length")
12227      (if_then_else (match_operand:SI 0 "register_operand" "")
12228         (const_string "2")
12229         (const_string "*")))])
12231 (define_insn "*lshrsi3_one_bit_cconly"
12232   [(set (reg FLAGS_REG)
12233         (compare
12234           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12235                        (match_operand:QI 2 "const1_operand" ""))
12236           (const_int 0)))
12237    (clobber (match_scratch:SI 0 "=r"))]
12238   "ix86_match_ccmode (insn, CCGOCmode)
12239    && (TARGET_SHIFT1 || optimize_size)
12240    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12241   "shr{l}\t%0"
12242   [(set_attr "type" "ishift")
12243    (set_attr "length" "2")])
12245 (define_insn "*lshrsi3_cmp_one_bit_zext"
12246   [(set (reg FLAGS_REG)
12247         (compare
12248           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12249                        (match_operand:QI 2 "const1_operand" ""))
12250           (const_int 0)))
12251    (set (match_operand:DI 0 "register_operand" "=r")
12252         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12253   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12254    && (TARGET_SHIFT1 || optimize_size)
12255    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12256   "shr{l}\t%k0"
12257   [(set_attr "type" "ishift")
12258    (set_attr "length" "2")])
12260 ;; This pattern can't accept a variable shift count, since shifts by
12261 ;; zero don't affect the flags.  We assume that shifts by constant
12262 ;; zero are optimized away.
12263 (define_insn "*lshrsi3_cmp"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268           (const_int 0)))
12269    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12270         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12271   "ix86_match_ccmode (insn, CCGOCmode)
12272    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12273    && (optimize_size
12274        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12275   "shr{l}\t{%2, %0|%0, %2}"
12276   [(set_attr "type" "ishift")
12277    (set_attr "mode" "SI")])
12279 (define_insn "*lshrsi3_cconly"
12280   [(set (reg FLAGS_REG)
12281       (compare
12282         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12283                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12284         (const_int 0)))
12285    (clobber (match_scratch:SI 0 "=r"))]
12286   "ix86_match_ccmode (insn, CCGOCmode)
12287    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12288    && (optimize_size
12289        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12290   "shr{l}\t{%2, %0|%0, %2}"
12291   [(set_attr "type" "ishift")
12292    (set_attr "mode" "SI")])
12294 (define_insn "*lshrsi3_cmp_zext"
12295   [(set (reg FLAGS_REG)
12296         (compare
12297           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12298                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12299           (const_int 0)))
12300    (set (match_operand:DI 0 "register_operand" "=r")
12301         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12302   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12303    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12304    && (optimize_size
12305        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12306   "shr{l}\t{%2, %k0|%k0, %2}"
12307   [(set_attr "type" "ishift")
12308    (set_attr "mode" "SI")])
12310 (define_expand "lshrhi3"
12311   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12312         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12313                      (match_operand:QI 2 "nonmemory_operand" "")))
12314    (clobber (reg:CC FLAGS_REG))]
12315   "TARGET_HIMODE_MATH"
12316   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12318 (define_insn "*lshrhi3_1_one_bit"
12319   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12320         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12321                      (match_operand:QI 2 "const1_operand" "")))
12322    (clobber (reg:CC FLAGS_REG))]
12323   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12324    && (TARGET_SHIFT1 || optimize_size)"
12325   "shr{w}\t%0"
12326   [(set_attr "type" "ishift")
12327    (set (attr "length")
12328      (if_then_else (match_operand 0 "register_operand" "")
12329         (const_string "2")
12330         (const_string "*")))])
12332 (define_insn "*lshrhi3_1"
12333   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12334         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12335                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12336    (clobber (reg:CC FLAGS_REG))]
12337   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12338   "@
12339    shr{w}\t{%2, %0|%0, %2}
12340    shr{w}\t{%b2, %0|%0, %b2}"
12341   [(set_attr "type" "ishift")
12342    (set_attr "mode" "HI")])
12344 ;; This pattern can't accept a variable shift count, since shifts by
12345 ;; zero don't affect the flags.  We assume that shifts by constant
12346 ;; zero are optimized away.
12347 (define_insn "*lshrhi3_one_bit_cmp"
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    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12354         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12355   "ix86_match_ccmode (insn, CCGOCmode)
12356    && (TARGET_SHIFT1 || optimize_size)
12357    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12358   "shr{w}\t%0"
12359   [(set_attr "type" "ishift")
12360    (set (attr "length")
12361      (if_then_else (match_operand:SI 0 "register_operand" "")
12362         (const_string "2")
12363         (const_string "*")))])
12365 (define_insn "*lshrhi3_one_bit_cconly"
12366   [(set (reg FLAGS_REG)
12367         (compare
12368           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12369                        (match_operand:QI 2 "const1_operand" ""))
12370           (const_int 0)))
12371    (clobber (match_scratch:HI 0 "=r"))]
12372   "ix86_match_ccmode (insn, CCGOCmode)
12373    && (TARGET_SHIFT1 || optimize_size)
12374    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12375   "shr{w}\t%0"
12376   [(set_attr "type" "ishift")
12377    (set_attr "length" "2")])
12379 ;; This pattern can't accept a variable shift count, since shifts by
12380 ;; zero don't affect the flags.  We assume that shifts by constant
12381 ;; zero are optimized away.
12382 (define_insn "*lshrhi3_cmp"
12383   [(set (reg FLAGS_REG)
12384         (compare
12385           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12386                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12387           (const_int 0)))
12388    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12389         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12390   "ix86_match_ccmode (insn, CCGOCmode)
12391    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12392    && (optimize_size
12393        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12394   "shr{w}\t{%2, %0|%0, %2}"
12395   [(set_attr "type" "ishift")
12396    (set_attr "mode" "HI")])
12398 (define_insn "*lshrhi3_cconly"
12399   [(set (reg FLAGS_REG)
12400         (compare
12401           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12402                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12403           (const_int 0)))
12404    (clobber (match_scratch:HI 0 "=r"))]
12405   "ix86_match_ccmode (insn, CCGOCmode)
12406    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12407    && (optimize_size
12408        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12409   "shr{w}\t{%2, %0|%0, %2}"
12410   [(set_attr "type" "ishift")
12411    (set_attr "mode" "HI")])
12413 (define_expand "lshrqi3"
12414   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12415         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12416                      (match_operand:QI 2 "nonmemory_operand" "")))
12417    (clobber (reg:CC FLAGS_REG))]
12418   "TARGET_QIMODE_MATH"
12419   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12421 (define_insn "*lshrqi3_1_one_bit"
12422   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12423         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12424                      (match_operand:QI 2 "const1_operand" "")))
12425    (clobber (reg:CC FLAGS_REG))]
12426   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12427    && (TARGET_SHIFT1 || optimize_size)"
12428   "shr{b}\t%0"
12429   [(set_attr "type" "ishift")
12430    (set (attr "length")
12431      (if_then_else (match_operand 0 "register_operand" "")
12432         (const_string "2")
12433         (const_string "*")))])
12435 (define_insn "*lshrqi3_1_one_bit_slp"
12436   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12437         (lshiftrt:QI (match_dup 0)
12438                      (match_operand:QI 1 "const1_operand" "")))
12439    (clobber (reg:CC FLAGS_REG))]
12440   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12441    && (TARGET_SHIFT1 || optimize_size)"
12442   "shr{b}\t%0"
12443   [(set_attr "type" "ishift1")
12444    (set (attr "length")
12445      (if_then_else (match_operand 0 "register_operand" "")
12446         (const_string "2")
12447         (const_string "*")))])
12449 (define_insn "*lshrqi3_1"
12450   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12451         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12452                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12453    (clobber (reg:CC FLAGS_REG))]
12454   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12455   "@
12456    shr{b}\t{%2, %0|%0, %2}
12457    shr{b}\t{%b2, %0|%0, %b2}"
12458   [(set_attr "type" "ishift")
12459    (set_attr "mode" "QI")])
12461 (define_insn "*lshrqi3_1_slp"
12462   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12463         (lshiftrt:QI (match_dup 0)
12464                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12465    (clobber (reg:CC FLAGS_REG))]
12466   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12468   "@
12469    shr{b}\t{%1, %0|%0, %1}
12470    shr{b}\t{%b1, %0|%0, %b1}"
12471   [(set_attr "type" "ishift1")
12472    (set_attr "mode" "QI")])
12474 ;; This pattern can't accept a variable shift count, since shifts by
12475 ;; zero don't affect the flags.  We assume that shifts by constant
12476 ;; zero are optimized away.
12477 (define_insn "*lshrqi2_one_bit_cmp"
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    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12484         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12485   "ix86_match_ccmode (insn, CCGOCmode)
12486    && (TARGET_SHIFT1 || optimize_size)
12487    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12488   "shr{b}\t%0"
12489   [(set_attr "type" "ishift")
12490    (set (attr "length")
12491      (if_then_else (match_operand:SI 0 "register_operand" "")
12492         (const_string "2")
12493         (const_string "*")))])
12495 (define_insn "*lshrqi2_one_bit_cconly"
12496   [(set (reg FLAGS_REG)
12497         (compare
12498           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12499                        (match_operand:QI 2 "const1_operand" ""))
12500           (const_int 0)))
12501    (clobber (match_scratch:QI 0 "=q"))]
12502   "ix86_match_ccmode (insn, CCGOCmode)
12503    && (TARGET_SHIFT1 || optimize_size)
12504    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12505   "shr{b}\t%0"
12506   [(set_attr "type" "ishift")
12507    (set_attr "length" "2")])
12509 ;; This pattern can't accept a variable shift count, since shifts by
12510 ;; zero don't affect the flags.  We assume that shifts by constant
12511 ;; zero are optimized away.
12512 (define_insn "*lshrqi2_cmp"
12513   [(set (reg FLAGS_REG)
12514         (compare
12515           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12516                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12517           (const_int 0)))
12518    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12519         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12520   "ix86_match_ccmode (insn, CCGOCmode)
12521    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12522    && (optimize_size
12523        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12524   "shr{b}\t{%2, %0|%0, %2}"
12525   [(set_attr "type" "ishift")
12526    (set_attr "mode" "QI")])
12528 (define_insn "*lshrqi2_cconly"
12529   [(set (reg FLAGS_REG)
12530         (compare
12531           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12532                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12533           (const_int 0)))
12534    (clobber (match_scratch:QI 0 "=q"))]
12535   "ix86_match_ccmode (insn, CCGOCmode)
12536    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12537    && (optimize_size
12538        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12539   "shr{b}\t{%2, %0|%0, %2}"
12540   [(set_attr "type" "ishift")
12541    (set_attr "mode" "QI")])
12543 ;; Rotate instructions
12545 (define_expand "rotldi3"
12546   [(set (match_operand:DI 0 "shiftdi_operand" "")
12547         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12548                    (match_operand:QI 2 "nonmemory_operand" "")))
12549    (clobber (reg:CC FLAGS_REG))]
12550  ""
12552   if (TARGET_64BIT)
12553     {
12554       ix86_expand_binary_operator (ROTATE, DImode, operands);
12555       DONE;
12556     }
12557   if (!const_1_to_31_operand (operands[2], VOIDmode))
12558     FAIL;
12559   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12560   DONE;
12563 ;; Implement rotation using two double-precision shift instructions
12564 ;; and a scratch register.
12565 (define_insn_and_split "ix86_rotldi3"
12566  [(set (match_operand:DI 0 "register_operand" "=r")
12567        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12568                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12569   (clobber (reg:CC FLAGS_REG))
12570   (clobber (match_scratch:SI 3 "=&r"))]
12571  "!TARGET_64BIT"
12572  ""
12573  "&& reload_completed"
12574  [(set (match_dup 3) (match_dup 4))
12575   (parallel
12576    [(set (match_dup 4)
12577          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12578                  (lshiftrt:SI (match_dup 5)
12579                               (minus:QI (const_int 32) (match_dup 2)))))
12580     (clobber (reg:CC FLAGS_REG))])
12581   (parallel
12582    [(set (match_dup 5)
12583          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12584                  (lshiftrt:SI (match_dup 3)
12585                               (minus:QI (const_int 32) (match_dup 2)))))
12586     (clobber (reg:CC FLAGS_REG))])]
12587  "split_di (operands, 1, operands + 4, operands + 5);")
12589 (define_insn "*rotlsi3_1_one_bit_rex64"
12590   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12591         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12592                    (match_operand:QI 2 "const1_operand" "")))
12593    (clobber (reg:CC FLAGS_REG))]
12594   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12595    && (TARGET_SHIFT1 || optimize_size)"
12596   "rol{q}\t%0"
12597   [(set_attr "type" "rotate")
12598    (set (attr "length")
12599      (if_then_else (match_operand:DI 0 "register_operand" "")
12600         (const_string "2")
12601         (const_string "*")))])
12603 (define_insn "*rotldi3_1_rex64"
12604   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12605         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12606                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12607    (clobber (reg:CC FLAGS_REG))]
12608   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12609   "@
12610    rol{q}\t{%2, %0|%0, %2}
12611    rol{q}\t{%b2, %0|%0, %b2}"
12612   [(set_attr "type" "rotate")
12613    (set_attr "mode" "DI")])
12615 (define_expand "rotlsi3"
12616   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12617         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12618                    (match_operand:QI 2 "nonmemory_operand" "")))
12619    (clobber (reg:CC FLAGS_REG))]
12620   ""
12621   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12623 (define_insn "*rotlsi3_1_one_bit"
12624   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12625         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12626                    (match_operand:QI 2 "const1_operand" "")))
12627    (clobber (reg:CC FLAGS_REG))]
12628   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12629    && (TARGET_SHIFT1 || optimize_size)"
12630   "rol{l}\t%0"
12631   [(set_attr "type" "rotate")
12632    (set (attr "length")
12633      (if_then_else (match_operand:SI 0 "register_operand" "")
12634         (const_string "2")
12635         (const_string "*")))])
12637 (define_insn "*rotlsi3_1_one_bit_zext"
12638   [(set (match_operand:DI 0 "register_operand" "=r")
12639         (zero_extend:DI
12640           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12641                      (match_operand:QI 2 "const1_operand" ""))))
12642    (clobber (reg:CC FLAGS_REG))]
12643   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12644    && (TARGET_SHIFT1 || optimize_size)"
12645   "rol{l}\t%k0"
12646   [(set_attr "type" "rotate")
12647    (set_attr "length" "2")])
12649 (define_insn "*rotlsi3_1"
12650   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12651         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12652                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12653    (clobber (reg:CC FLAGS_REG))]
12654   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12655   "@
12656    rol{l}\t{%2, %0|%0, %2}
12657    rol{l}\t{%b2, %0|%0, %b2}"
12658   [(set_attr "type" "rotate")
12659    (set_attr "mode" "SI")])
12661 (define_insn "*rotlsi3_1_zext"
12662   [(set (match_operand:DI 0 "register_operand" "=r,r")
12663         (zero_extend:DI
12664           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12665                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12666    (clobber (reg:CC FLAGS_REG))]
12667   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12668   "@
12669    rol{l}\t{%2, %k0|%k0, %2}
12670    rol{l}\t{%b2, %k0|%k0, %b2}"
12671   [(set_attr "type" "rotate")
12672    (set_attr "mode" "SI")])
12674 (define_expand "rotlhi3"
12675   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12676         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12677                    (match_operand:QI 2 "nonmemory_operand" "")))
12678    (clobber (reg:CC FLAGS_REG))]
12679   "TARGET_HIMODE_MATH"
12680   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12682 (define_insn "*rotlhi3_1_one_bit"
12683   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12684         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12685                    (match_operand:QI 2 "const1_operand" "")))
12686    (clobber (reg:CC FLAGS_REG))]
12687   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12688    && (TARGET_SHIFT1 || optimize_size)"
12689   "rol{w}\t%0"
12690   [(set_attr "type" "rotate")
12691    (set (attr "length")
12692      (if_then_else (match_operand 0 "register_operand" "")
12693         (const_string "2")
12694         (const_string "*")))])
12696 (define_insn "*rotlhi3_1"
12697   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12698         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12699                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12700    (clobber (reg:CC FLAGS_REG))]
12701   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12702   "@
12703    rol{w}\t{%2, %0|%0, %2}
12704    rol{w}\t{%b2, %0|%0, %b2}"
12705   [(set_attr "type" "rotate")
12706    (set_attr "mode" "HI")])
12708 (define_expand "rotlqi3"
12709   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12710         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12711                    (match_operand:QI 2 "nonmemory_operand" "")))
12712    (clobber (reg:CC FLAGS_REG))]
12713   "TARGET_QIMODE_MATH"
12714   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12716 (define_insn "*rotlqi3_1_one_bit_slp"
12717   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12718         (rotate:QI (match_dup 0)
12719                    (match_operand:QI 1 "const1_operand" "")))
12720    (clobber (reg:CC FLAGS_REG))]
12721   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12722    && (TARGET_SHIFT1 || optimize_size)"
12723   "rol{b}\t%0"
12724   [(set_attr "type" "rotate1")
12725    (set (attr "length")
12726      (if_then_else (match_operand 0 "register_operand" "")
12727         (const_string "2")
12728         (const_string "*")))])
12730 (define_insn "*rotlqi3_1_one_bit"
12731   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12732         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12733                    (match_operand:QI 2 "const1_operand" "")))
12734    (clobber (reg:CC FLAGS_REG))]
12735   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12736    && (TARGET_SHIFT1 || optimize_size)"
12737   "rol{b}\t%0"
12738   [(set_attr "type" "rotate")
12739    (set (attr "length")
12740      (if_then_else (match_operand 0 "register_operand" "")
12741         (const_string "2")
12742         (const_string "*")))])
12744 (define_insn "*rotlqi3_1_slp"
12745   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12746         (rotate:QI (match_dup 0)
12747                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12748    (clobber (reg:CC FLAGS_REG))]
12749   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12750    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12751   "@
12752    rol{b}\t{%1, %0|%0, %1}
12753    rol{b}\t{%b1, %0|%0, %b1}"
12754   [(set_attr "type" "rotate1")
12755    (set_attr "mode" "QI")])
12757 (define_insn "*rotlqi3_1"
12758   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12759         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12760                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12761    (clobber (reg:CC FLAGS_REG))]
12762   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12763   "@
12764    rol{b}\t{%2, %0|%0, %2}
12765    rol{b}\t{%b2, %0|%0, %b2}"
12766   [(set_attr "type" "rotate")
12767    (set_attr "mode" "QI")])
12769 (define_expand "rotrdi3"
12770   [(set (match_operand:DI 0 "shiftdi_operand" "")
12771         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12772                    (match_operand:QI 2 "nonmemory_operand" "")))
12773    (clobber (reg:CC FLAGS_REG))]
12774  ""
12776   if (TARGET_64BIT)
12777     {
12778       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12779       DONE;
12780     }
12781   if (!const_1_to_31_operand (operands[2], VOIDmode))
12782     FAIL;
12783   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12784   DONE;
12787 ;; Implement rotation using two double-precision shift instructions
12788 ;; and a scratch register.
12789 (define_insn_and_split "ix86_rotrdi3"
12790  [(set (match_operand:DI 0 "register_operand" "=r")
12791        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12792                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12793   (clobber (reg:CC FLAGS_REG))
12794   (clobber (match_scratch:SI 3 "=&r"))]
12795  "!TARGET_64BIT"
12796  ""
12797  "&& reload_completed"
12798  [(set (match_dup 3) (match_dup 4))
12799   (parallel
12800    [(set (match_dup 4)
12801          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12802                  (ashift:SI (match_dup 5)
12803                             (minus:QI (const_int 32) (match_dup 2)))))
12804     (clobber (reg:CC FLAGS_REG))])
12805   (parallel
12806    [(set (match_dup 5)
12807          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12808                  (ashift:SI (match_dup 3)
12809                             (minus:QI (const_int 32) (match_dup 2)))))
12810     (clobber (reg:CC FLAGS_REG))])]
12811  "split_di (operands, 1, operands + 4, operands + 5);")
12813 (define_insn "*rotrdi3_1_one_bit_rex64"
12814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12815         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12816                      (match_operand:QI 2 "const1_operand" "")))
12817    (clobber (reg:CC FLAGS_REG))]
12818   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12819    && (TARGET_SHIFT1 || optimize_size)"
12820   "ror{q}\t%0"
12821   [(set_attr "type" "rotate")
12822    (set (attr "length")
12823      (if_then_else (match_operand:DI 0 "register_operand" "")
12824         (const_string "2")
12825         (const_string "*")))])
12827 (define_insn "*rotrdi3_1_rex64"
12828   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12829         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12830                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12831    (clobber (reg:CC FLAGS_REG))]
12832   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12833   "@
12834    ror{q}\t{%2, %0|%0, %2}
12835    ror{q}\t{%b2, %0|%0, %b2}"
12836   [(set_attr "type" "rotate")
12837    (set_attr "mode" "DI")])
12839 (define_expand "rotrsi3"
12840   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12841         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12842                      (match_operand:QI 2 "nonmemory_operand" "")))
12843    (clobber (reg:CC FLAGS_REG))]
12844   ""
12845   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12847 (define_insn "*rotrsi3_1_one_bit"
12848   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12849         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12850                      (match_operand:QI 2 "const1_operand" "")))
12851    (clobber (reg:CC FLAGS_REG))]
12852   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12853    && (TARGET_SHIFT1 || optimize_size)"
12854   "ror{l}\t%0"
12855   [(set_attr "type" "rotate")
12856    (set (attr "length")
12857      (if_then_else (match_operand:SI 0 "register_operand" "")
12858         (const_string "2")
12859         (const_string "*")))])
12861 (define_insn "*rotrsi3_1_one_bit_zext"
12862   [(set (match_operand:DI 0 "register_operand" "=r")
12863         (zero_extend:DI
12864           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12865                        (match_operand:QI 2 "const1_operand" ""))))
12866    (clobber (reg:CC FLAGS_REG))]
12867   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12868    && (TARGET_SHIFT1 || optimize_size)"
12869   "ror{l}\t%k0"
12870   [(set_attr "type" "rotate")
12871    (set (attr "length")
12872      (if_then_else (match_operand:SI 0 "register_operand" "")
12873         (const_string "2")
12874         (const_string "*")))])
12876 (define_insn "*rotrsi3_1"
12877   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12878         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12879                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12880    (clobber (reg:CC FLAGS_REG))]
12881   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12882   "@
12883    ror{l}\t{%2, %0|%0, %2}
12884    ror{l}\t{%b2, %0|%0, %b2}"
12885   [(set_attr "type" "rotate")
12886    (set_attr "mode" "SI")])
12888 (define_insn "*rotrsi3_1_zext"
12889   [(set (match_operand:DI 0 "register_operand" "=r,r")
12890         (zero_extend:DI
12891           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12892                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12893    (clobber (reg:CC FLAGS_REG))]
12894   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12895   "@
12896    ror{l}\t{%2, %k0|%k0, %2}
12897    ror{l}\t{%b2, %k0|%k0, %b2}"
12898   [(set_attr "type" "rotate")
12899    (set_attr "mode" "SI")])
12901 (define_expand "rotrhi3"
12902   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12903         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12904                      (match_operand:QI 2 "nonmemory_operand" "")))
12905    (clobber (reg:CC FLAGS_REG))]
12906   "TARGET_HIMODE_MATH"
12907   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12909 (define_insn "*rotrhi3_one_bit"
12910   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12911         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12912                      (match_operand:QI 2 "const1_operand" "")))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12915    && (TARGET_SHIFT1 || optimize_size)"
12916   "ror{w}\t%0"
12917   [(set_attr "type" "rotate")
12918    (set (attr "length")
12919      (if_then_else (match_operand 0 "register_operand" "")
12920         (const_string "2")
12921         (const_string "*")))])
12923 (define_insn "*rotrhi3"
12924   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12925         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12926                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12929   "@
12930    ror{w}\t{%2, %0|%0, %2}
12931    ror{w}\t{%b2, %0|%0, %b2}"
12932   [(set_attr "type" "rotate")
12933    (set_attr "mode" "HI")])
12935 (define_expand "rotrqi3"
12936   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12937         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12938                      (match_operand:QI 2 "nonmemory_operand" "")))
12939    (clobber (reg:CC FLAGS_REG))]
12940   "TARGET_QIMODE_MATH"
12941   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12943 (define_insn "*rotrqi3_1_one_bit"
12944   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12945         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12946                      (match_operand:QI 2 "const1_operand" "")))
12947    (clobber (reg:CC FLAGS_REG))]
12948   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12949    && (TARGET_SHIFT1 || optimize_size)"
12950   "ror{b}\t%0"
12951   [(set_attr "type" "rotate")
12952    (set (attr "length")
12953      (if_then_else (match_operand 0 "register_operand" "")
12954         (const_string "2")
12955         (const_string "*")))])
12957 (define_insn "*rotrqi3_1_one_bit_slp"
12958   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12959         (rotatert:QI (match_dup 0)
12960                      (match_operand:QI 1 "const1_operand" "")))
12961    (clobber (reg:CC FLAGS_REG))]
12962   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12963    && (TARGET_SHIFT1 || optimize_size)"
12964   "ror{b}\t%0"
12965   [(set_attr "type" "rotate1")
12966    (set (attr "length")
12967      (if_then_else (match_operand 0 "register_operand" "")
12968         (const_string "2")
12969         (const_string "*")))])
12971 (define_insn "*rotrqi3_1"
12972   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12973         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12974                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12975    (clobber (reg:CC FLAGS_REG))]
12976   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12977   "@
12978    ror{b}\t{%2, %0|%0, %2}
12979    ror{b}\t{%b2, %0|%0, %b2}"
12980   [(set_attr "type" "rotate")
12981    (set_attr "mode" "QI")])
12983 (define_insn "*rotrqi3_1_slp"
12984   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12985         (rotatert:QI (match_dup 0)
12986                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12987    (clobber (reg:CC FLAGS_REG))]
12988   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12989    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12990   "@
12991    ror{b}\t{%1, %0|%0, %1}
12992    ror{b}\t{%b1, %0|%0, %b1}"
12993   [(set_attr "type" "rotate1")
12994    (set_attr "mode" "QI")])
12996 ;; Bit set / bit test instructions
12998 (define_expand "extv"
12999   [(set (match_operand:SI 0 "register_operand" "")
13000         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13001                          (match_operand:SI 2 "const8_operand" "")
13002                          (match_operand:SI 3 "const8_operand" "")))]
13003   ""
13005   /* Handle extractions from %ah et al.  */
13006   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13007     FAIL;
13009   /* From mips.md: extract_bit_field doesn't verify that our source
13010      matches the predicate, so check it again here.  */
13011   if (! ext_register_operand (operands[1], VOIDmode))
13012     FAIL;
13015 (define_expand "extzv"
13016   [(set (match_operand:SI 0 "register_operand" "")
13017         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13018                          (match_operand:SI 2 "const8_operand" "")
13019                          (match_operand:SI 3 "const8_operand" "")))]
13020   ""
13022   /* Handle extractions from %ah et al.  */
13023   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13024     FAIL;
13026   /* From mips.md: extract_bit_field doesn't verify that our source
13027      matches the predicate, so check it again here.  */
13028   if (! ext_register_operand (operands[1], VOIDmode))
13029     FAIL;
13032 (define_expand "insv"
13033   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13034                       (match_operand 1 "const8_operand" "")
13035                       (match_operand 2 "const8_operand" ""))
13036         (match_operand 3 "register_operand" ""))]
13037   ""
13039   /* Handle insertions to %ah et al.  */
13040   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13041     FAIL;
13043   /* From mips.md: insert_bit_field doesn't verify that our source
13044      matches the predicate, so check it again here.  */
13045   if (! ext_register_operand (operands[0], VOIDmode))
13046     FAIL;
13048   if (TARGET_64BIT)
13049     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13050   else
13051     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13053   DONE;
13056 ;; %%% bts, btr, btc, bt.
13057 ;; In general these instructions are *slow* when applied to memory,
13058 ;; since they enforce atomic operation.  When applied to registers,
13059 ;; it depends on the cpu implementation.  They're never faster than
13060 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13061 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13062 ;; within the instruction itself, so operating on bits in the high
13063 ;; 32-bits of a register becomes easier.
13065 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13066 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13067 ;; negdf respectively, so they can never be disabled entirely.
13069 (define_insn "*btsq"
13070   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13071                          (const_int 1)
13072                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13073         (const_int 1))
13074    (clobber (reg:CC FLAGS_REG))]
13075   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13076   "bts{q} %1,%0"
13077   [(set_attr "type" "alu1")])
13079 (define_insn "*btrq"
13080   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13081                          (const_int 1)
13082                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13083         (const_int 0))
13084    (clobber (reg:CC FLAGS_REG))]
13085   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13086   "btr{q} %1,%0"
13087   [(set_attr "type" "alu1")])
13089 (define_insn "*btcq"
13090   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13091                          (const_int 1)
13092                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13093         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13094    (clobber (reg:CC FLAGS_REG))]
13095   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13096   "btc{q} %1,%0"
13097   [(set_attr "type" "alu1")])
13099 ;; Allow Nocona to avoid these instructions if a register is available.
13101 (define_peephole2
13102   [(match_scratch:DI 2 "r")
13103    (parallel [(set (zero_extract:DI
13104                      (match_operand:DI 0 "register_operand" "")
13105                      (const_int 1)
13106                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13107                    (const_int 1))
13108               (clobber (reg:CC FLAGS_REG))])]
13109   "TARGET_64BIT && !TARGET_USE_BT"
13110   [(const_int 0)]
13112   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13113   rtx op1;
13115   if (HOST_BITS_PER_WIDE_INT >= 64)
13116     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13117   else if (i < HOST_BITS_PER_WIDE_INT)
13118     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13119   else
13120     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13122   op1 = immed_double_const (lo, hi, DImode);
13123   if (i >= 31)
13124     {
13125       emit_move_insn (operands[2], op1);
13126       op1 = operands[2];
13127     }
13129   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13130   DONE;
13133 (define_peephole2
13134   [(match_scratch:DI 2 "r")
13135    (parallel [(set (zero_extract:DI
13136                      (match_operand:DI 0 "register_operand" "")
13137                      (const_int 1)
13138                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13139                    (const_int 0))
13140               (clobber (reg:CC FLAGS_REG))])]
13141   "TARGET_64BIT && !TARGET_USE_BT"
13142   [(const_int 0)]
13144   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13145   rtx op1;
13147   if (HOST_BITS_PER_WIDE_INT >= 64)
13148     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13149   else if (i < HOST_BITS_PER_WIDE_INT)
13150     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13151   else
13152     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13154   op1 = immed_double_const (~lo, ~hi, DImode);
13155   if (i >= 32)
13156     {
13157       emit_move_insn (operands[2], op1);
13158       op1 = operands[2];
13159     }
13161   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13162   DONE;
13165 (define_peephole2
13166   [(match_scratch:DI 2 "r")
13167    (parallel [(set (zero_extract:DI
13168                      (match_operand:DI 0 "register_operand" "")
13169                      (const_int 1)
13170                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13171               (not:DI (zero_extract:DI
13172                         (match_dup 0) (const_int 1) (match_dup 1))))
13173               (clobber (reg:CC FLAGS_REG))])]
13174   "TARGET_64BIT && !TARGET_USE_BT"
13175   [(const_int 0)]
13177   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13178   rtx op1;
13180   if (HOST_BITS_PER_WIDE_INT >= 64)
13181     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13182   else if (i < HOST_BITS_PER_WIDE_INT)
13183     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13184   else
13185     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13187   op1 = immed_double_const (lo, hi, DImode);
13188   if (i >= 31)
13189     {
13190       emit_move_insn (operands[2], op1);
13191       op1 = operands[2];
13192     }
13194   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13195   DONE;
13198 ;; Store-flag instructions.
13200 ;; For all sCOND expanders, also expand the compare or test insn that
13201 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13203 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13204 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13205 ;; way, which can later delete the movzx if only QImode is needed.
13207 (define_expand "seq"
13208   [(set (match_operand:QI 0 "register_operand" "")
13209         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210   ""
13211   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13213 (define_expand "sne"
13214   [(set (match_operand:QI 0 "register_operand" "")
13215         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13216   ""
13217   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13219 (define_expand "sgt"
13220   [(set (match_operand:QI 0 "register_operand" "")
13221         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13222   ""
13223   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13225 (define_expand "sgtu"
13226   [(set (match_operand:QI 0 "register_operand" "")
13227         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228   ""
13229   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13231 (define_expand "slt"
13232   [(set (match_operand:QI 0 "register_operand" "")
13233         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234   ""
13235   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13237 (define_expand "sltu"
13238   [(set (match_operand:QI 0 "register_operand" "")
13239         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240   ""
13241   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13243 (define_expand "sge"
13244   [(set (match_operand:QI 0 "register_operand" "")
13245         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246   ""
13247   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13249 (define_expand "sgeu"
13250   [(set (match_operand:QI 0 "register_operand" "")
13251         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252   ""
13253   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13255 (define_expand "sle"
13256   [(set (match_operand:QI 0 "register_operand" "")
13257         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258   ""
13259   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13261 (define_expand "sleu"
13262   [(set (match_operand:QI 0 "register_operand" "")
13263         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264   ""
13265   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13267 (define_expand "sunordered"
13268   [(set (match_operand:QI 0 "register_operand" "")
13269         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270   "TARGET_80387 || TARGET_SSE"
13271   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13273 (define_expand "sordered"
13274   [(set (match_operand:QI 0 "register_operand" "")
13275         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276   "TARGET_80387"
13277   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13279 (define_expand "suneq"
13280   [(set (match_operand:QI 0 "register_operand" "")
13281         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282   "TARGET_80387 || TARGET_SSE"
13283   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13285 (define_expand "sunge"
13286   [(set (match_operand:QI 0 "register_operand" "")
13287         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13288   "TARGET_80387 || TARGET_SSE"
13289   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13291 (define_expand "sungt"
13292   [(set (match_operand:QI 0 "register_operand" "")
13293         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294   "TARGET_80387 || TARGET_SSE"
13295   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13297 (define_expand "sunle"
13298   [(set (match_operand:QI 0 "register_operand" "")
13299         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13300   "TARGET_80387 || TARGET_SSE"
13301   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13303 (define_expand "sunlt"
13304   [(set (match_operand:QI 0 "register_operand" "")
13305         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13306   "TARGET_80387 || TARGET_SSE"
13307   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13309 (define_expand "sltgt"
13310   [(set (match_operand:QI 0 "register_operand" "")
13311         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13312   "TARGET_80387 || TARGET_SSE"
13313   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13315 (define_insn "*setcc_1"
13316   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13317         (match_operator:QI 1 "ix86_comparison_operator"
13318           [(reg FLAGS_REG) (const_int 0)]))]
13319   ""
13320   "set%C1\t%0"
13321   [(set_attr "type" "setcc")
13322    (set_attr "mode" "QI")])
13324 (define_insn "*setcc_2"
13325   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13326         (match_operator:QI 1 "ix86_comparison_operator"
13327           [(reg FLAGS_REG) (const_int 0)]))]
13328   ""
13329   "set%C1\t%0"
13330   [(set_attr "type" "setcc")
13331    (set_attr "mode" "QI")])
13333 ;; In general it is not safe to assume too much about CCmode registers,
13334 ;; so simplify-rtx stops when it sees a second one.  Under certain
13335 ;; conditions this is safe on x86, so help combine not create
13337 ;;      seta    %al
13338 ;;      testb   %al, %al
13339 ;;      sete    %al
13341 (define_split
13342   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13343         (ne:QI (match_operator 1 "ix86_comparison_operator"
13344                  [(reg FLAGS_REG) (const_int 0)])
13345             (const_int 0)))]
13346   ""
13347   [(set (match_dup 0) (match_dup 1))]
13349   PUT_MODE (operands[1], QImode);
13352 (define_split
13353   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13354         (ne:QI (match_operator 1 "ix86_comparison_operator"
13355                  [(reg FLAGS_REG) (const_int 0)])
13356             (const_int 0)))]
13357   ""
13358   [(set (match_dup 0) (match_dup 1))]
13360   PUT_MODE (operands[1], QImode);
13363 (define_split
13364   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13365         (eq:QI (match_operator 1 "ix86_comparison_operator"
13366                  [(reg FLAGS_REG) (const_int 0)])
13367             (const_int 0)))]
13368   ""
13369   [(set (match_dup 0) (match_dup 1))]
13371   rtx new_op1 = copy_rtx (operands[1]);
13372   operands[1] = new_op1;
13373   PUT_MODE (new_op1, QImode);
13374   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13375                                              GET_MODE (XEXP (new_op1, 0))));
13377   /* Make sure that (a) the CCmode we have for the flags is strong
13378      enough for the reversed compare or (b) we have a valid FP compare.  */
13379   if (! ix86_comparison_operator (new_op1, VOIDmode))
13380     FAIL;
13383 (define_split
13384   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13385         (eq:QI (match_operator 1 "ix86_comparison_operator"
13386                  [(reg FLAGS_REG) (const_int 0)])
13387             (const_int 0)))]
13388   ""
13389   [(set (match_dup 0) (match_dup 1))]
13391   rtx new_op1 = copy_rtx (operands[1]);
13392   operands[1] = new_op1;
13393   PUT_MODE (new_op1, QImode);
13394   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13395                                              GET_MODE (XEXP (new_op1, 0))));
13397   /* Make sure that (a) the CCmode we have for the flags is strong
13398      enough for the reversed compare or (b) we have a valid FP compare.  */
13399   if (! ix86_comparison_operator (new_op1, VOIDmode))
13400     FAIL;
13403 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13404 ;; subsequent logical operations are used to imitate conditional moves.
13405 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13406 ;; it directly.
13408 (define_insn "*sse_setccsf"
13409   [(set (match_operand:SF 0 "register_operand" "=x")
13410         (match_operator:SF 1 "sse_comparison_operator"
13411           [(match_operand:SF 2 "register_operand" "0")
13412            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13413   "TARGET_SSE"
13414   "cmp%D1ss\t{%3, %0|%0, %3}"
13415   [(set_attr "type" "ssecmp")
13416    (set_attr "mode" "SF")])
13418 (define_insn "*sse_setccdf"
13419   [(set (match_operand:DF 0 "register_operand" "=Y")
13420         (match_operator:DF 1 "sse_comparison_operator"
13421           [(match_operand:DF 2 "register_operand" "0")
13422            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13423   "TARGET_SSE2"
13424   "cmp%D1sd\t{%3, %0|%0, %3}"
13425   [(set_attr "type" "ssecmp")
13426    (set_attr "mode" "DF")])
13428 ;; Basic conditional jump instructions.
13429 ;; We ignore the overflow flag for signed branch instructions.
13431 ;; For all bCOND expanders, also expand the compare or test insn that
13432 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13434 (define_expand "beq"
13435   [(set (pc)
13436         (if_then_else (match_dup 1)
13437                       (label_ref (match_operand 0 "" ""))
13438                       (pc)))]
13439   ""
13440   "ix86_expand_branch (EQ, operands[0]); DONE;")
13442 (define_expand "bne"
13443   [(set (pc)
13444         (if_then_else (match_dup 1)
13445                       (label_ref (match_operand 0 "" ""))
13446                       (pc)))]
13447   ""
13448   "ix86_expand_branch (NE, operands[0]); DONE;")
13450 (define_expand "bgt"
13451   [(set (pc)
13452         (if_then_else (match_dup 1)
13453                       (label_ref (match_operand 0 "" ""))
13454                       (pc)))]
13455   ""
13456   "ix86_expand_branch (GT, operands[0]); DONE;")
13458 (define_expand "bgtu"
13459   [(set (pc)
13460         (if_then_else (match_dup 1)
13461                       (label_ref (match_operand 0 "" ""))
13462                       (pc)))]
13463   ""
13464   "ix86_expand_branch (GTU, operands[0]); DONE;")
13466 (define_expand "blt"
13467   [(set (pc)
13468         (if_then_else (match_dup 1)
13469                       (label_ref (match_operand 0 "" ""))
13470                       (pc)))]
13471   ""
13472   "ix86_expand_branch (LT, operands[0]); DONE;")
13474 (define_expand "bltu"
13475   [(set (pc)
13476         (if_then_else (match_dup 1)
13477                       (label_ref (match_operand 0 "" ""))
13478                       (pc)))]
13479   ""
13480   "ix86_expand_branch (LTU, operands[0]); DONE;")
13482 (define_expand "bge"
13483   [(set (pc)
13484         (if_then_else (match_dup 1)
13485                       (label_ref (match_operand 0 "" ""))
13486                       (pc)))]
13487   ""
13488   "ix86_expand_branch (GE, operands[0]); DONE;")
13490 (define_expand "bgeu"
13491   [(set (pc)
13492         (if_then_else (match_dup 1)
13493                       (label_ref (match_operand 0 "" ""))
13494                       (pc)))]
13495   ""
13496   "ix86_expand_branch (GEU, operands[0]); DONE;")
13498 (define_expand "ble"
13499   [(set (pc)
13500         (if_then_else (match_dup 1)
13501                       (label_ref (match_operand 0 "" ""))
13502                       (pc)))]
13503   ""
13504   "ix86_expand_branch (LE, operands[0]); DONE;")
13506 (define_expand "bleu"
13507   [(set (pc)
13508         (if_then_else (match_dup 1)
13509                       (label_ref (match_operand 0 "" ""))
13510                       (pc)))]
13511   ""
13512   "ix86_expand_branch (LEU, operands[0]); DONE;")
13514 (define_expand "bunordered"
13515   [(set (pc)
13516         (if_then_else (match_dup 1)
13517                       (label_ref (match_operand 0 "" ""))
13518                       (pc)))]
13519   "TARGET_80387 || TARGET_SSE_MATH"
13520   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13522 (define_expand "bordered"
13523   [(set (pc)
13524         (if_then_else (match_dup 1)
13525                       (label_ref (match_operand 0 "" ""))
13526                       (pc)))]
13527   "TARGET_80387 || TARGET_SSE_MATH"
13528   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13530 (define_expand "buneq"
13531   [(set (pc)
13532         (if_then_else (match_dup 1)
13533                       (label_ref (match_operand 0 "" ""))
13534                       (pc)))]
13535   "TARGET_80387 || TARGET_SSE_MATH"
13536   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13538 (define_expand "bunge"
13539   [(set (pc)
13540         (if_then_else (match_dup 1)
13541                       (label_ref (match_operand 0 "" ""))
13542                       (pc)))]
13543   "TARGET_80387 || TARGET_SSE_MATH"
13544   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13546 (define_expand "bungt"
13547   [(set (pc)
13548         (if_then_else (match_dup 1)
13549                       (label_ref (match_operand 0 "" ""))
13550                       (pc)))]
13551   "TARGET_80387 || TARGET_SSE_MATH"
13552   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13554 (define_expand "bunle"
13555   [(set (pc)
13556         (if_then_else (match_dup 1)
13557                       (label_ref (match_operand 0 "" ""))
13558                       (pc)))]
13559   "TARGET_80387 || TARGET_SSE_MATH"
13560   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13562 (define_expand "bunlt"
13563   [(set (pc)
13564         (if_then_else (match_dup 1)
13565                       (label_ref (match_operand 0 "" ""))
13566                       (pc)))]
13567   "TARGET_80387 || TARGET_SSE_MATH"
13568   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13570 (define_expand "bltgt"
13571   [(set (pc)
13572         (if_then_else (match_dup 1)
13573                       (label_ref (match_operand 0 "" ""))
13574                       (pc)))]
13575   "TARGET_80387 || TARGET_SSE_MATH"
13576   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13578 (define_insn "*jcc_1"
13579   [(set (pc)
13580         (if_then_else (match_operator 1 "ix86_comparison_operator"
13581                                       [(reg FLAGS_REG) (const_int 0)])
13582                       (label_ref (match_operand 0 "" ""))
13583                       (pc)))]
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 (define_insn "*jcc_2"
13597   [(set (pc)
13598         (if_then_else (match_operator 1 "ix86_comparison_operator"
13599                                       [(reg FLAGS_REG) (const_int 0)])
13600                       (pc)
13601                       (label_ref (match_operand 0 "" ""))))]
13602   ""
13603   "%+j%c1\t%l0"
13604   [(set_attr "type" "ibr")
13605    (set_attr "modrm" "0")
13606    (set (attr "length")
13607            (if_then_else (and (ge (minus (match_dup 0) (pc))
13608                                   (const_int -126))
13609                               (lt (minus (match_dup 0) (pc))
13610                                   (const_int 128)))
13611              (const_int 2)
13612              (const_int 6)))])
13614 ;; In general it is not safe to assume too much about CCmode registers,
13615 ;; so simplify-rtx stops when it sees a second one.  Under certain
13616 ;; conditions this is safe on x86, so help combine not create
13618 ;;      seta    %al
13619 ;;      testb   %al, %al
13620 ;;      je      Lfoo
13622 (define_split
13623   [(set (pc)
13624         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13625                                       [(reg FLAGS_REG) (const_int 0)])
13626                           (const_int 0))
13627                       (label_ref (match_operand 1 "" ""))
13628                       (pc)))]
13629   ""
13630   [(set (pc)
13631         (if_then_else (match_dup 0)
13632                       (label_ref (match_dup 1))
13633                       (pc)))]
13635   PUT_MODE (operands[0], VOIDmode);
13638 (define_split
13639   [(set (pc)
13640         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13641                                       [(reg FLAGS_REG) (const_int 0)])
13642                           (const_int 0))
13643                       (label_ref (match_operand 1 "" ""))
13644                       (pc)))]
13645   ""
13646   [(set (pc)
13647         (if_then_else (match_dup 0)
13648                       (label_ref (match_dup 1))
13649                       (pc)))]
13651   rtx new_op0 = copy_rtx (operands[0]);
13652   operands[0] = new_op0;
13653   PUT_MODE (new_op0, VOIDmode);
13654   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13655                                              GET_MODE (XEXP (new_op0, 0))));
13657   /* Make sure that (a) the CCmode we have for the flags is strong
13658      enough for the reversed compare or (b) we have a valid FP compare.  */
13659   if (! ix86_comparison_operator (new_op0, VOIDmode))
13660     FAIL;
13663 ;; Define combination compare-and-branch fp compare instructions to use
13664 ;; during early optimization.  Splitting the operation apart early makes
13665 ;; for bad code when we want to reverse the operation.
13667 (define_insn "*fp_jcc_1_mixed"
13668   [(set (pc)
13669         (if_then_else (match_operator 0 "comparison_operator"
13670                         [(match_operand 1 "register_operand" "f,x")
13671                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13672           (label_ref (match_operand 3 "" ""))
13673           (pc)))
13674    (clobber (reg:CCFP FPSR_REG))
13675    (clobber (reg:CCFP FLAGS_REG))]
13676   "TARGET_MIX_SSE_I387
13677    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13678    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13679    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13680   "#")
13682 (define_insn "*fp_jcc_1_sse"
13683   [(set (pc)
13684         (if_then_else (match_operator 0 "comparison_operator"
13685                         [(match_operand 1 "register_operand" "x")
13686                          (match_operand 2 "nonimmediate_operand" "xm")])
13687           (label_ref (match_operand 3 "" ""))
13688           (pc)))
13689    (clobber (reg:CCFP FPSR_REG))
13690    (clobber (reg:CCFP FLAGS_REG))]
13691   "TARGET_SSE_MATH
13692    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13693    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13694    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13695   "#")
13697 (define_insn "*fp_jcc_1_387"
13698   [(set (pc)
13699         (if_then_else (match_operator 0 "comparison_operator"
13700                         [(match_operand 1 "register_operand" "f")
13701                          (match_operand 2 "register_operand" "f")])
13702           (label_ref (match_operand 3 "" ""))
13703           (pc)))
13704    (clobber (reg:CCFP FPSR_REG))
13705    (clobber (reg:CCFP FLAGS_REG))]
13706   "TARGET_CMOVE && TARGET_80387
13707    && FLOAT_MODE_P (GET_MODE (operands[1]))
13708    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13709    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13710   "#")
13712 (define_insn "*fp_jcc_2_mixed"
13713   [(set (pc)
13714         (if_then_else (match_operator 0 "comparison_operator"
13715                         [(match_operand 1 "register_operand" "f,x")
13716                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13717           (pc)
13718           (label_ref (match_operand 3 "" ""))))
13719    (clobber (reg:CCFP FPSR_REG))
13720    (clobber (reg:CCFP FLAGS_REG))]
13721   "TARGET_MIX_SSE_I387
13722    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13723    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13724    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13725   "#")
13727 (define_insn "*fp_jcc_2_sse"
13728   [(set (pc)
13729         (if_then_else (match_operator 0 "comparison_operator"
13730                         [(match_operand 1 "register_operand" "x")
13731                          (match_operand 2 "nonimmediate_operand" "xm")])
13732           (pc)
13733           (label_ref (match_operand 3 "" ""))))
13734    (clobber (reg:CCFP FPSR_REG))
13735    (clobber (reg:CCFP FLAGS_REG))]
13736   "TARGET_SSE_MATH
13737    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13738    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13739    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13740   "#")
13742 (define_insn "*fp_jcc_2_387"
13743   [(set (pc)
13744         (if_then_else (match_operator 0 "comparison_operator"
13745                         [(match_operand 1 "register_operand" "f")
13746                          (match_operand 2 "register_operand" "f")])
13747           (pc)
13748           (label_ref (match_operand 3 "" ""))))
13749    (clobber (reg:CCFP FPSR_REG))
13750    (clobber (reg:CCFP FLAGS_REG))]
13751   "TARGET_CMOVE && TARGET_80387
13752    && FLOAT_MODE_P (GET_MODE (operands[1]))
13753    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13754    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13755   "#")
13757 (define_insn "*fp_jcc_3_387"
13758   [(set (pc)
13759         (if_then_else (match_operator 0 "comparison_operator"
13760                         [(match_operand 1 "register_operand" "f")
13761                          (match_operand 2 "nonimmediate_operand" "fm")])
13762           (label_ref (match_operand 3 "" ""))
13763           (pc)))
13764    (clobber (reg:CCFP FPSR_REG))
13765    (clobber (reg:CCFP FLAGS_REG))
13766    (clobber (match_scratch:HI 4 "=a"))]
13767   "TARGET_80387
13768    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13769    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13770    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13771    && SELECT_CC_MODE (GET_CODE (operands[0]),
13772                       operands[1], operands[2]) == CCFPmode
13773    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13774   "#")
13776 (define_insn "*fp_jcc_4_387"
13777   [(set (pc)
13778         (if_then_else (match_operator 0 "comparison_operator"
13779                         [(match_operand 1 "register_operand" "f")
13780                          (match_operand 2 "nonimmediate_operand" "fm")])
13781           (pc)
13782           (label_ref (match_operand 3 "" ""))))
13783    (clobber (reg:CCFP FPSR_REG))
13784    (clobber (reg:CCFP FLAGS_REG))
13785    (clobber (match_scratch:HI 4 "=a"))]
13786   "TARGET_80387
13787    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13788    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13789    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13790    && SELECT_CC_MODE (GET_CODE (operands[0]),
13791                       operands[1], operands[2]) == CCFPmode
13792    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13793   "#")
13795 (define_insn "*fp_jcc_5_387"
13796   [(set (pc)
13797         (if_then_else (match_operator 0 "comparison_operator"
13798                         [(match_operand 1 "register_operand" "f")
13799                          (match_operand 2 "register_operand" "f")])
13800           (label_ref (match_operand 3 "" ""))
13801           (pc)))
13802    (clobber (reg:CCFP FPSR_REG))
13803    (clobber (reg:CCFP FLAGS_REG))
13804    (clobber (match_scratch:HI 4 "=a"))]
13805   "TARGET_80387
13806    && FLOAT_MODE_P (GET_MODE (operands[1]))
13807    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13808    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13809   "#")
13811 (define_insn "*fp_jcc_6_387"
13812   [(set (pc)
13813         (if_then_else (match_operator 0 "comparison_operator"
13814                         [(match_operand 1 "register_operand" "f")
13815                          (match_operand 2 "register_operand" "f")])
13816           (pc)
13817           (label_ref (match_operand 3 "" ""))))
13818    (clobber (reg:CCFP FPSR_REG))
13819    (clobber (reg:CCFP FLAGS_REG))
13820    (clobber (match_scratch:HI 4 "=a"))]
13821   "TARGET_80387
13822    && FLOAT_MODE_P (GET_MODE (operands[1]))
13823    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13824    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13825   "#")
13827 (define_insn "*fp_jcc_7_387"
13828   [(set (pc)
13829         (if_then_else (match_operator 0 "comparison_operator"
13830                         [(match_operand 1 "register_operand" "f")
13831                          (match_operand 2 "const0_operand" "X")])
13832           (label_ref (match_operand 3 "" ""))
13833           (pc)))
13834    (clobber (reg:CCFP FPSR_REG))
13835    (clobber (reg:CCFP FLAGS_REG))
13836    (clobber (match_scratch:HI 4 "=a"))]
13837   "TARGET_80387
13838    && FLOAT_MODE_P (GET_MODE (operands[1]))
13839    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13840    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13841    && SELECT_CC_MODE (GET_CODE (operands[0]),
13842                       operands[1], operands[2]) == CCFPmode
13843    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13844   "#")
13846 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13847 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13848 ;; with a precedence over other operators and is always put in the first
13849 ;; place. Swap condition and operands to match ficom instruction.
13851 (define_insn "*fp_jcc_8<mode>_387"
13852   [(set (pc)
13853         (if_then_else (match_operator 0 "comparison_operator"
13854                         [(match_operator 1 "float_operator"
13855                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13856                            (match_operand 3 "register_operand" "f,f")])
13857           (label_ref (match_operand 4 "" ""))
13858           (pc)))
13859    (clobber (reg:CCFP FPSR_REG))
13860    (clobber (reg:CCFP FLAGS_REG))
13861    (clobber (match_scratch:HI 5 "=a,a"))]
13862   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13863    && FLOAT_MODE_P (GET_MODE (operands[3]))
13864    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13865    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13866    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13867    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13868   "#")
13870 (define_split
13871   [(set (pc)
13872         (if_then_else (match_operator 0 "comparison_operator"
13873                         [(match_operand 1 "register_operand" "")
13874                          (match_operand 2 "nonimmediate_operand" "")])
13875           (match_operand 3 "" "")
13876           (match_operand 4 "" "")))
13877    (clobber (reg:CCFP FPSR_REG))
13878    (clobber (reg:CCFP FLAGS_REG))]
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], NULL_RTX, NULL_RTX);
13884   DONE;
13887 (define_split
13888   [(set (pc)
13889         (if_then_else (match_operator 0 "comparison_operator"
13890                         [(match_operand 1 "register_operand" "")
13891                          (match_operand 2 "general_operand" "")])
13892           (match_operand 3 "" "")
13893           (match_operand 4 "" "")))
13894    (clobber (reg:CCFP FPSR_REG))
13895    (clobber (reg:CCFP FLAGS_REG))
13896    (clobber (match_scratch:HI 5 "=a"))]
13897   "reload_completed"
13898   [(const_int 0)]
13900   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13901                         operands[3], operands[4], operands[5], NULL_RTX);
13902   DONE;
13905 (define_split
13906   [(set (pc)
13907         (if_then_else (match_operator 0 "comparison_operator"
13908                         [(match_operator 1 "float_operator"
13909                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13910                            (match_operand 3 "register_operand" "")])
13911           (match_operand 4 "" "")
13912           (match_operand 5 "" "")))
13913    (clobber (reg:CCFP FPSR_REG))
13914    (clobber (reg:CCFP FLAGS_REG))
13915    (clobber (match_scratch:HI 6 "=a"))]
13916   "reload_completed"
13917   [(const_int 0)]
13919   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13920   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13921                         operands[3], operands[7],
13922                         operands[4], operands[5], operands[6], NULL_RTX);
13923   DONE;
13926 ;; %%% Kill this when reload knows how to do it.
13927 (define_split
13928   [(set (pc)
13929         (if_then_else (match_operator 0 "comparison_operator"
13930                         [(match_operator 1 "float_operator"
13931                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13932                            (match_operand 3 "register_operand" "")])
13933           (match_operand 4 "" "")
13934           (match_operand 5 "" "")))
13935    (clobber (reg:CCFP FPSR_REG))
13936    (clobber (reg:CCFP FLAGS_REG))
13937    (clobber (match_scratch:HI 6 "=a"))]
13938   "reload_completed"
13939   [(const_int 0)]
13941   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13942   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13943   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13944                         operands[3], operands[7],
13945                         operands[4], operands[5], operands[6], operands[2]);
13946   DONE;
13949 ;; Unconditional and other jump instructions
13951 (define_insn "jump"
13952   [(set (pc)
13953         (label_ref (match_operand 0 "" "")))]
13954   ""
13955   "jmp\t%l0"
13956   [(set_attr "type" "ibr")
13957    (set (attr "length")
13958            (if_then_else (and (ge (minus (match_dup 0) (pc))
13959                                   (const_int -126))
13960                               (lt (minus (match_dup 0) (pc))
13961                                   (const_int 128)))
13962              (const_int 2)
13963              (const_int 5)))
13964    (set_attr "modrm" "0")])
13966 (define_expand "indirect_jump"
13967   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13968   ""
13969   "")
13971 (define_insn "*indirect_jump"
13972   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13973   "!TARGET_64BIT"
13974   "jmp\t%A0"
13975   [(set_attr "type" "ibr")
13976    (set_attr "length_immediate" "0")])
13978 (define_insn "*indirect_jump_rtx64"
13979   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13980   "TARGET_64BIT"
13981   "jmp\t%A0"
13982   [(set_attr "type" "ibr")
13983    (set_attr "length_immediate" "0")])
13985 (define_expand "tablejump"
13986   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13987               (use (label_ref (match_operand 1 "" "")))])]
13988   ""
13990   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13991      relative.  Convert the relative address to an absolute address.  */
13992   if (flag_pic)
13993     {
13994       rtx op0, op1;
13995       enum rtx_code code;
13997       if (TARGET_64BIT)
13998         {
13999           code = PLUS;
14000           op0 = operands[0];
14001           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14002         }
14003       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14004         {
14005           code = PLUS;
14006           op0 = operands[0];
14007           op1 = pic_offset_table_rtx;
14008         }
14009       else
14010         {
14011           code = MINUS;
14012           op0 = pic_offset_table_rtx;
14013           op1 = operands[0];
14014         }
14016       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14017                                          OPTAB_DIRECT);
14018     }
14021 (define_insn "*tablejump_1"
14022   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14023    (use (label_ref (match_operand 1 "" "")))]
14024   "!TARGET_64BIT"
14025   "jmp\t%A0"
14026   [(set_attr "type" "ibr")
14027    (set_attr "length_immediate" "0")])
14029 (define_insn "*tablejump_1_rtx64"
14030   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14031    (use (label_ref (match_operand 1 "" "")))]
14032   "TARGET_64BIT"
14033   "jmp\t%A0"
14034   [(set_attr "type" "ibr")
14035    (set_attr "length_immediate" "0")])
14037 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14039 (define_peephole2
14040   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14041    (set (match_operand:QI 1 "register_operand" "")
14042         (match_operator:QI 2 "ix86_comparison_operator"
14043           [(reg FLAGS_REG) (const_int 0)]))
14044    (set (match_operand 3 "q_regs_operand" "")
14045         (zero_extend (match_dup 1)))]
14046   "(peep2_reg_dead_p (3, operands[1])
14047     || operands_match_p (operands[1], operands[3]))
14048    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14049   [(set (match_dup 4) (match_dup 0))
14050    (set (strict_low_part (match_dup 5))
14051         (match_dup 2))]
14053   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14054   operands[5] = gen_lowpart (QImode, operands[3]);
14055   ix86_expand_clear (operands[3]);
14058 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14060 (define_peephole2
14061   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14062    (set (match_operand:QI 1 "register_operand" "")
14063         (match_operator:QI 2 "ix86_comparison_operator"
14064           [(reg FLAGS_REG) (const_int 0)]))
14065    (parallel [(set (match_operand 3 "q_regs_operand" "")
14066                    (zero_extend (match_dup 1)))
14067               (clobber (reg:CC FLAGS_REG))])]
14068   "(peep2_reg_dead_p (3, operands[1])
14069     || operands_match_p (operands[1], operands[3]))
14070    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14071   [(set (match_dup 4) (match_dup 0))
14072    (set (strict_low_part (match_dup 5))
14073         (match_dup 2))]
14075   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14076   operands[5] = gen_lowpart (QImode, operands[3]);
14077   ix86_expand_clear (operands[3]);
14080 ;; Call instructions.
14082 ;; The predicates normally associated with named expanders are not properly
14083 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14084 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14086 ;; Call subroutine returning no value.
14088 (define_expand "call_pop"
14089   [(parallel [(call (match_operand:QI 0 "" "")
14090                     (match_operand:SI 1 "" ""))
14091               (set (reg:SI SP_REG)
14092                    (plus:SI (reg:SI SP_REG)
14093                             (match_operand:SI 3 "" "")))])]
14094   "!TARGET_64BIT"
14096   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14097   DONE;
14100 (define_insn "*call_pop_0"
14101   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14102          (match_operand:SI 1 "" ""))
14103    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14104                             (match_operand:SI 2 "immediate_operand" "")))]
14105   "!TARGET_64BIT"
14107   if (SIBLING_CALL_P (insn))
14108     return "jmp\t%P0";
14109   else
14110     return "call\t%P0";
14112   [(set_attr "type" "call")])
14114 (define_insn "*call_pop_1"
14115   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14116          (match_operand:SI 1 "" ""))
14117    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14118                             (match_operand:SI 2 "immediate_operand" "i")))]
14119   "!TARGET_64BIT"
14121   if (constant_call_address_operand (operands[0], Pmode))
14122     {
14123       if (SIBLING_CALL_P (insn))
14124         return "jmp\t%P0";
14125       else
14126         return "call\t%P0";
14127     }
14128   if (SIBLING_CALL_P (insn))
14129     return "jmp\t%A0";
14130   else
14131     return "call\t%A0";
14133   [(set_attr "type" "call")])
14135 (define_expand "call"
14136   [(call (match_operand:QI 0 "" "")
14137          (match_operand 1 "" ""))
14138    (use (match_operand 2 "" ""))]
14139   ""
14141   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14142   DONE;
14145 (define_expand "sibcall"
14146   [(call (match_operand:QI 0 "" "")
14147          (match_operand 1 "" ""))
14148    (use (match_operand 2 "" ""))]
14149   ""
14151   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14152   DONE;
14155 (define_insn "*call_0"
14156   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14157          (match_operand 1 "" ""))]
14158   ""
14160   if (SIBLING_CALL_P (insn))
14161     return "jmp\t%P0";
14162   else
14163     return "call\t%P0";
14165   [(set_attr "type" "call")])
14167 (define_insn "*call_1"
14168   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14169          (match_operand 1 "" ""))]
14170   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14172   if (constant_call_address_operand (operands[0], Pmode))
14173     return "call\t%P0";
14174   return "call\t%A0";
14176   [(set_attr "type" "call")])
14178 (define_insn "*sibcall_1"
14179   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14180          (match_operand 1 "" ""))]
14181   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14183   if (constant_call_address_operand (operands[0], Pmode))
14184     return "jmp\t%P0";
14185   return "jmp\t%A0";
14187   [(set_attr "type" "call")])
14189 (define_insn "*call_1_rex64"
14190   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14191          (match_operand 1 "" ""))]
14192   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14194   if (constant_call_address_operand (operands[0], Pmode))
14195     return "call\t%P0";
14196   return "call\t%A0";
14198   [(set_attr "type" "call")])
14200 (define_insn "*sibcall_1_rex64"
14201   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14202          (match_operand 1 "" ""))]
14203   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14204   "jmp\t%P0"
14205   [(set_attr "type" "call")])
14207 (define_insn "*sibcall_1_rex64_v"
14208   [(call (mem:QI (reg:DI R11_REG))
14209          (match_operand 0 "" ""))]
14210   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14211   "jmp\t*%%r11"
14212   [(set_attr "type" "call")])
14215 ;; Call subroutine, returning value in operand 0
14217 (define_expand "call_value_pop"
14218   [(parallel [(set (match_operand 0 "" "")
14219                    (call (match_operand:QI 1 "" "")
14220                          (match_operand:SI 2 "" "")))
14221               (set (reg:SI SP_REG)
14222                    (plus:SI (reg:SI SP_REG)
14223                             (match_operand:SI 4 "" "")))])]
14224   "!TARGET_64BIT"
14226   ix86_expand_call (operands[0], operands[1], operands[2],
14227                     operands[3], operands[4], 0);
14228   DONE;
14231 (define_expand "call_value"
14232   [(set (match_operand 0 "" "")
14233         (call (match_operand:QI 1 "" "")
14234               (match_operand:SI 2 "" "")))
14235    (use (match_operand:SI 3 "" ""))]
14236   ;; Operand 2 not used on the i386.
14237   ""
14239   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14240   DONE;
14243 (define_expand "sibcall_value"
14244   [(set (match_operand 0 "" "")
14245         (call (match_operand:QI 1 "" "")
14246               (match_operand:SI 2 "" "")))
14247    (use (match_operand:SI 3 "" ""))]
14248   ;; Operand 2 not used on the i386.
14249   ""
14251   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14252   DONE;
14255 ;; Call subroutine returning any type.
14257 (define_expand "untyped_call"
14258   [(parallel [(call (match_operand 0 "" "")
14259                     (const_int 0))
14260               (match_operand 1 "" "")
14261               (match_operand 2 "" "")])]
14262   ""
14264   int i;
14266   /* In order to give reg-stack an easier job in validating two
14267      coprocessor registers as containing a possible return value,
14268      simply pretend the untyped call returns a complex long double
14269      value.  */
14271   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14272                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14273                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14274                     NULL, 0);
14276   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14277     {
14278       rtx set = XVECEXP (operands[2], 0, i);
14279       emit_move_insn (SET_DEST (set), SET_SRC (set));
14280     }
14282   /* The optimizer does not know that the call sets the function value
14283      registers we stored in the result block.  We avoid problems by
14284      claiming that all hard registers are used and clobbered at this
14285      point.  */
14286   emit_insn (gen_blockage (const0_rtx));
14288   DONE;
14291 ;; Prologue and epilogue instructions
14293 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14294 ;; all of memory.  This blocks insns from being moved across this point.
14296 (define_insn "blockage"
14297   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14298   ""
14299   ""
14300   [(set_attr "length" "0")])
14302 ;; Insn emitted into the body of a function to return from a function.
14303 ;; This is only done if the function's epilogue is known to be simple.
14304 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14306 (define_expand "return"
14307   [(return)]
14308   "ix86_can_use_return_insn_p ()"
14310   if (current_function_pops_args)
14311     {
14312       rtx popc = GEN_INT (current_function_pops_args);
14313       emit_jump_insn (gen_return_pop_internal (popc));
14314       DONE;
14315     }
14318 (define_insn "return_internal"
14319   [(return)]
14320   "reload_completed"
14321   "ret"
14322   [(set_attr "length" "1")
14323    (set_attr "length_immediate" "0")
14324    (set_attr "modrm" "0")])
14326 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14327 ;; instruction Athlon and K8 have.
14329 (define_insn "return_internal_long"
14330   [(return)
14331    (unspec [(const_int 0)] UNSPEC_REP)]
14332   "reload_completed"
14333   "rep {;} ret"
14334   [(set_attr "length" "1")
14335    (set_attr "length_immediate" "0")
14336    (set_attr "prefix_rep" "1")
14337    (set_attr "modrm" "0")])
14339 (define_insn "return_pop_internal"
14340   [(return)
14341    (use (match_operand:SI 0 "const_int_operand" ""))]
14342   "reload_completed"
14343   "ret\t%0"
14344   [(set_attr "length" "3")
14345    (set_attr "length_immediate" "2")
14346    (set_attr "modrm" "0")])
14348 (define_insn "return_indirect_internal"
14349   [(return)
14350    (use (match_operand:SI 0 "register_operand" "r"))]
14351   "reload_completed"
14352   "jmp\t%A0"
14353   [(set_attr "type" "ibr")
14354    (set_attr "length_immediate" "0")])
14356 (define_insn "nop"
14357   [(const_int 0)]
14358   ""
14359   "nop"
14360   [(set_attr "length" "1")
14361    (set_attr "length_immediate" "0")
14362    (set_attr "modrm" "0")])
14364 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14365 ;; branch prediction penalty for the third jump in a 16-byte
14366 ;; block on K8.
14368 (define_insn "align"
14369   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14370   ""
14372 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14373   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14374 #else
14375   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14376      The align insn is used to avoid 3 jump instructions in the row to improve
14377      branch prediction and the benefits hardly outweigh the cost of extra 8
14378      nops on the average inserted by full alignment pseudo operation.  */
14379 #endif
14380   return "";
14382   [(set_attr "length" "16")])
14384 (define_expand "prologue"
14385   [(const_int 1)]
14386   ""
14387   "ix86_expand_prologue (); DONE;")
14389 (define_insn "set_got"
14390   [(set (match_operand:SI 0 "register_operand" "=r")
14391         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14392    (clobber (reg:CC FLAGS_REG))]
14393   "!TARGET_64BIT"
14394   { return output_set_got (operands[0], NULL_RTX); }
14395   [(set_attr "type" "multi")
14396    (set_attr "length" "12")])
14398 (define_insn "set_got_labelled"
14399   [(set (match_operand:SI 0 "register_operand" "=r")
14400         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14401          UNSPEC_SET_GOT))
14402    (clobber (reg:CC FLAGS_REG))]
14403   "!TARGET_64BIT"
14404   { return output_set_got (operands[0], operands[1]); }
14405   [(set_attr "type" "multi")
14406    (set_attr "length" "12")])
14408 (define_insn "set_got_rex64"
14409   [(set (match_operand:DI 0 "register_operand" "=r")
14410         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14411   "TARGET_64BIT"
14412   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14413   [(set_attr "type" "lea")
14414    (set_attr "length" "6")])
14416 (define_expand "epilogue"
14417   [(const_int 1)]
14418   ""
14419   "ix86_expand_epilogue (1); DONE;")
14421 (define_expand "sibcall_epilogue"
14422   [(const_int 1)]
14423   ""
14424   "ix86_expand_epilogue (0); DONE;")
14426 (define_expand "eh_return"
14427   [(use (match_operand 0 "register_operand" ""))]
14428   ""
14430   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14432   /* Tricky bit: we write the address of the handler to which we will
14433      be returning into someone else's stack frame, one word below the
14434      stack address we wish to restore.  */
14435   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14436   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14437   tmp = gen_rtx_MEM (Pmode, tmp);
14438   emit_move_insn (tmp, ra);
14440   if (Pmode == SImode)
14441     emit_jump_insn (gen_eh_return_si (sa));
14442   else
14443     emit_jump_insn (gen_eh_return_di (sa));
14444   emit_barrier ();
14445   DONE;
14448 (define_insn_and_split "eh_return_si"
14449   [(set (pc)
14450         (unspec [(match_operand:SI 0 "register_operand" "c")]
14451                  UNSPEC_EH_RETURN))]
14452   "!TARGET_64BIT"
14453   "#"
14454   "reload_completed"
14455   [(const_int 1)]
14456   "ix86_expand_epilogue (2); DONE;")
14458 (define_insn_and_split "eh_return_di"
14459   [(set (pc)
14460         (unspec [(match_operand:DI 0 "register_operand" "c")]
14461                  UNSPEC_EH_RETURN))]
14462   "TARGET_64BIT"
14463   "#"
14464   "reload_completed"
14465   [(const_int 1)]
14466   "ix86_expand_epilogue (2); DONE;")
14468 (define_insn "leave"
14469   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14470    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14471    (clobber (mem:BLK (scratch)))]
14472   "!TARGET_64BIT"
14473   "leave"
14474   [(set_attr "type" "leave")])
14476 (define_insn "leave_rex64"
14477   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14478    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14479    (clobber (mem:BLK (scratch)))]
14480   "TARGET_64BIT"
14481   "leave"
14482   [(set_attr "type" "leave")])
14484 (define_expand "ffssi2"
14485   [(parallel
14486      [(set (match_operand:SI 0 "register_operand" "")
14487            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14488       (clobber (match_scratch:SI 2 ""))
14489       (clobber (reg:CC FLAGS_REG))])]
14490   ""
14491   "")
14493 (define_insn_and_split "*ffs_cmove"
14494   [(set (match_operand:SI 0 "register_operand" "=r")
14495         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14496    (clobber (match_scratch:SI 2 "=&r"))
14497    (clobber (reg:CC FLAGS_REG))]
14498   "TARGET_CMOVE"
14499   "#"
14500   "&& reload_completed"
14501   [(set (match_dup 2) (const_int -1))
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 (match_dup 0) (if_then_else:SI
14505                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14506                         (match_dup 2)
14507                         (match_dup 0)))
14508    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14509               (clobber (reg:CC FLAGS_REG))])]
14510   "")
14512 (define_insn_and_split "*ffs_no_cmove"
14513   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14514         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14515    (clobber (match_scratch:SI 2 "=&q"))
14516    (clobber (reg:CC FLAGS_REG))]
14517   ""
14518   "#"
14519   "reload_completed"
14520   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14521               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14522    (set (strict_low_part (match_dup 3))
14523         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14524    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14525               (clobber (reg:CC FLAGS_REG))])
14526    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14527               (clobber (reg:CC FLAGS_REG))])
14528    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14529               (clobber (reg:CC FLAGS_REG))])]
14531   operands[3] = gen_lowpart (QImode, operands[2]);
14532   ix86_expand_clear (operands[2]);
14535 (define_insn "*ffssi_1"
14536   [(set (reg:CCZ FLAGS_REG)
14537         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14538                      (const_int 0)))
14539    (set (match_operand:SI 0 "register_operand" "=r")
14540         (ctz:SI (match_dup 1)))]
14541   ""
14542   "bsf{l}\t{%1, %0|%0, %1}"
14543   [(set_attr "prefix_0f" "1")])
14545 (define_expand "ffsdi2"
14546   [(parallel
14547      [(set (match_operand:DI 0 "register_operand" "")
14548            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14549       (clobber (match_scratch:DI 2 ""))
14550       (clobber (reg:CC FLAGS_REG))])]
14551   "TARGET_64BIT && TARGET_CMOVE"
14552   "")
14554 (define_insn_and_split "*ffs_rex64"
14555   [(set (match_operand:DI 0 "register_operand" "=r")
14556         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14557    (clobber (match_scratch:DI 2 "=&r"))
14558    (clobber (reg:CC FLAGS_REG))]
14559   "TARGET_64BIT && TARGET_CMOVE"
14560   "#"
14561   "&& reload_completed"
14562   [(set (match_dup 2) (const_int -1))
14563    (parallel [(set (reg:CCZ FLAGS_REG)
14564                    (compare:CCZ (match_dup 1) (const_int 0)))
14565               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14566    (set (match_dup 0) (if_then_else:DI
14567                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14568                         (match_dup 2)
14569                         (match_dup 0)))
14570    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14571               (clobber (reg:CC FLAGS_REG))])]
14572   "")
14574 (define_insn "*ffsdi_1"
14575   [(set (reg:CCZ FLAGS_REG)
14576         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14577                      (const_int 0)))
14578    (set (match_operand:DI 0 "register_operand" "=r")
14579         (ctz:DI (match_dup 1)))]
14580   "TARGET_64BIT"
14581   "bsf{q}\t{%1, %0|%0, %1}"
14582   [(set_attr "prefix_0f" "1")])
14584 (define_insn "ctzsi2"
14585   [(set (match_operand:SI 0 "register_operand" "=r")
14586         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14587    (clobber (reg:CC FLAGS_REG))]
14588   ""
14589   "bsf{l}\t{%1, %0|%0, %1}"
14590   [(set_attr "prefix_0f" "1")])
14592 (define_insn "ctzdi2"
14593   [(set (match_operand:DI 0 "register_operand" "=r")
14594         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14595    (clobber (reg:CC FLAGS_REG))]
14596   "TARGET_64BIT"
14597   "bsf{q}\t{%1, %0|%0, %1}"
14598   [(set_attr "prefix_0f" "1")])
14600 (define_expand "clzsi2"
14601   [(parallel
14602      [(set (match_operand:SI 0 "register_operand" "")
14603            (minus:SI (const_int 31)
14604                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14605       (clobber (reg:CC FLAGS_REG))])
14606    (parallel
14607      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14608       (clobber (reg:CC FLAGS_REG))])]
14609   ""
14610   "")
14612 (define_insn "*bsr"
14613   [(set (match_operand:SI 0 "register_operand" "=r")
14614         (minus:SI (const_int 31)
14615                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14616    (clobber (reg:CC FLAGS_REG))]
14617   ""
14618   "bsr{l}\t{%1, %0|%0, %1}"
14619   [(set_attr "prefix_0f" "1")])
14621 (define_insn "bswapsi2"
14622   [(set (match_operand:SI 0 "register_operand" "=r")
14623         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14624    (clobber (reg:CC FLAGS_REG))]
14625   "TARGET_BSWAP"
14626   "bswap\t%k0"
14627   [(set_attr "prefix_0f" "1")
14628    (set_attr "length" "2")])
14630 (define_insn "bswapdi2"
14631   [(set (match_operand:DI 0 "register_operand" "=r")
14632         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14633    (clobber (reg:CC FLAGS_REG))]
14634   "TARGET_64BIT && TARGET_BSWAP"
14635   "bswap\t%0"
14636   [(set_attr "prefix_0f" "1")
14637    (set_attr "length" "3")])
14639 (define_expand "clzdi2"
14640   [(parallel
14641      [(set (match_operand:DI 0 "register_operand" "")
14642            (minus:DI (const_int 63)
14643                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14644       (clobber (reg:CC FLAGS_REG))])
14645    (parallel
14646      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14647       (clobber (reg:CC FLAGS_REG))])]
14648   "TARGET_64BIT"
14649   "")
14651 (define_insn "*bsr_rex64"
14652   [(set (match_operand:DI 0 "register_operand" "=r")
14653         (minus:DI (const_int 63)
14654                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14655    (clobber (reg:CC FLAGS_REG))]
14656   "TARGET_64BIT"
14657   "bsr{q}\t{%1, %0|%0, %1}"
14658   [(set_attr "prefix_0f" "1")])
14660 ;; Thread-local storage patterns for ELF.
14662 ;; Note that these code sequences must appear exactly as shown
14663 ;; in order to allow linker relaxation.
14665 (define_insn "*tls_global_dynamic_32_gnu"
14666   [(set (match_operand:SI 0 "register_operand" "=a")
14667         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14668                     (match_operand:SI 2 "tls_symbolic_operand" "")
14669                     (match_operand:SI 3 "call_insn_operand" "")]
14670                     UNSPEC_TLS_GD))
14671    (clobber (match_scratch:SI 4 "=d"))
14672    (clobber (match_scratch:SI 5 "=c"))
14673    (clobber (reg:CC FLAGS_REG))]
14674   "!TARGET_64BIT && TARGET_GNU_TLS"
14675   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14676   [(set_attr "type" "multi")
14677    (set_attr "length" "12")])
14679 (define_insn "*tls_global_dynamic_32_sun"
14680   [(set (match_operand:SI 0 "register_operand" "=a")
14681         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14682                     (match_operand:SI 2 "tls_symbolic_operand" "")
14683                     (match_operand:SI 3 "call_insn_operand" "")]
14684                     UNSPEC_TLS_GD))
14685    (clobber (match_scratch:SI 4 "=d"))
14686    (clobber (match_scratch:SI 5 "=c"))
14687    (clobber (reg:CC FLAGS_REG))]
14688   "!TARGET_64BIT && TARGET_SUN_TLS"
14689   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14690         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14691   [(set_attr "type" "multi")
14692    (set_attr "length" "14")])
14694 (define_expand "tls_global_dynamic_32"
14695   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14696                    (unspec:SI
14697                     [(match_dup 2)
14698                      (match_operand:SI 1 "tls_symbolic_operand" "")
14699                      (match_dup 3)]
14700                     UNSPEC_TLS_GD))
14701               (clobber (match_scratch:SI 4 ""))
14702               (clobber (match_scratch:SI 5 ""))
14703               (clobber (reg:CC FLAGS_REG))])]
14704   ""
14706   if (flag_pic)
14707     operands[2] = pic_offset_table_rtx;
14708   else
14709     {
14710       operands[2] = gen_reg_rtx (Pmode);
14711       emit_insn (gen_set_got (operands[2]));
14712     }
14713   if (TARGET_GNU2_TLS)
14714     {
14715        emit_insn (gen_tls_dynamic_gnu2_32
14716                   (operands[0], operands[1], operands[2]));
14717        DONE;
14718     }
14719   operands[3] = ix86_tls_get_addr ();
14722 (define_insn "*tls_global_dynamic_64"
14723   [(set (match_operand:DI 0 "register_operand" "=a")
14724         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14725                  (match_operand:DI 3 "" "")))
14726    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14727               UNSPEC_TLS_GD)]
14728   "TARGET_64BIT"
14729   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14730   [(set_attr "type" "multi")
14731    (set_attr "length" "16")])
14733 (define_expand "tls_global_dynamic_64"
14734   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14735                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14736               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14737                          UNSPEC_TLS_GD)])]
14738   ""
14740   if (TARGET_GNU2_TLS)
14741     {
14742        emit_insn (gen_tls_dynamic_gnu2_64
14743                   (operands[0], operands[1]));
14744        DONE;
14745     }
14746   operands[2] = ix86_tls_get_addr ();
14749 (define_insn "*tls_local_dynamic_base_32_gnu"
14750   [(set (match_operand:SI 0 "register_operand" "=a")
14751         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14752                     (match_operand:SI 2 "call_insn_operand" "")]
14753                    UNSPEC_TLS_LD_BASE))
14754    (clobber (match_scratch:SI 3 "=d"))
14755    (clobber (match_scratch:SI 4 "=c"))
14756    (clobber (reg:CC FLAGS_REG))]
14757   "!TARGET_64BIT && TARGET_GNU_TLS"
14758   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14759   [(set_attr "type" "multi")
14760    (set_attr "length" "11")])
14762 (define_insn "*tls_local_dynamic_base_32_sun"
14763   [(set (match_operand:SI 0 "register_operand" "=a")
14764         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14765                     (match_operand:SI 2 "call_insn_operand" "")]
14766                    UNSPEC_TLS_LD_BASE))
14767    (clobber (match_scratch:SI 3 "=d"))
14768    (clobber (match_scratch:SI 4 "=c"))
14769    (clobber (reg:CC FLAGS_REG))]
14770   "!TARGET_64BIT && TARGET_SUN_TLS"
14771   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14772         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14773   [(set_attr "type" "multi")
14774    (set_attr "length" "13")])
14776 (define_expand "tls_local_dynamic_base_32"
14777   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14778                    (unspec:SI [(match_dup 1) (match_dup 2)]
14779                               UNSPEC_TLS_LD_BASE))
14780               (clobber (match_scratch:SI 3 ""))
14781               (clobber (match_scratch:SI 4 ""))
14782               (clobber (reg:CC FLAGS_REG))])]
14783   ""
14785   if (flag_pic)
14786     operands[1] = pic_offset_table_rtx;
14787   else
14788     {
14789       operands[1] = gen_reg_rtx (Pmode);
14790       emit_insn (gen_set_got (operands[1]));
14791     }
14792   if (TARGET_GNU2_TLS)
14793     {
14794        emit_insn (gen_tls_dynamic_gnu2_32
14795                   (operands[0], ix86_tls_module_base (), operands[1]));
14796        DONE;
14797     }
14798   operands[2] = ix86_tls_get_addr ();
14801 (define_insn "*tls_local_dynamic_base_64"
14802   [(set (match_operand:DI 0 "register_operand" "=a")
14803         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14804                  (match_operand:DI 2 "" "")))
14805    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14806   "TARGET_64BIT"
14807   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14808   [(set_attr "type" "multi")
14809    (set_attr "length" "12")])
14811 (define_expand "tls_local_dynamic_base_64"
14812   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14813                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14814               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14815   ""
14817   if (TARGET_GNU2_TLS)
14818     {
14819        emit_insn (gen_tls_dynamic_gnu2_64
14820                   (operands[0], ix86_tls_module_base ()));
14821        DONE;
14822     }
14823   operands[1] = ix86_tls_get_addr ();
14826 ;; Local dynamic of a single variable is a lose.  Show combine how
14827 ;; to convert that back to global dynamic.
14829 (define_insn_and_split "*tls_local_dynamic_32_once"
14830   [(set (match_operand:SI 0 "register_operand" "=a")
14831         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14832                              (match_operand:SI 2 "call_insn_operand" "")]
14833                             UNSPEC_TLS_LD_BASE)
14834                  (const:SI (unspec:SI
14835                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14836                             UNSPEC_DTPOFF))))
14837    (clobber (match_scratch:SI 4 "=d"))
14838    (clobber (match_scratch:SI 5 "=c"))
14839    (clobber (reg:CC FLAGS_REG))]
14840   ""
14841   "#"
14842   ""
14843   [(parallel [(set (match_dup 0)
14844                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14845                               UNSPEC_TLS_GD))
14846               (clobber (match_dup 4))
14847               (clobber (match_dup 5))
14848               (clobber (reg:CC FLAGS_REG))])]
14849   "")
14851 ;; Load and add the thread base pointer from %gs:0.
14853 (define_insn "*load_tp_si"
14854   [(set (match_operand:SI 0 "register_operand" "=r")
14855         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14856   "!TARGET_64BIT"
14857   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14858   [(set_attr "type" "imov")
14859    (set_attr "modrm" "0")
14860    (set_attr "length" "7")
14861    (set_attr "memory" "load")
14862    (set_attr "imm_disp" "false")])
14864 (define_insn "*add_tp_si"
14865   [(set (match_operand:SI 0 "register_operand" "=r")
14866         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14867                  (match_operand:SI 1 "register_operand" "0")))
14868    (clobber (reg:CC FLAGS_REG))]
14869   "!TARGET_64BIT"
14870   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14871   [(set_attr "type" "alu")
14872    (set_attr "modrm" "0")
14873    (set_attr "length" "7")
14874    (set_attr "memory" "load")
14875    (set_attr "imm_disp" "false")])
14877 (define_insn "*load_tp_di"
14878   [(set (match_operand:DI 0 "register_operand" "=r")
14879         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14880   "TARGET_64BIT"
14881   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14882   [(set_attr "type" "imov")
14883    (set_attr "modrm" "0")
14884    (set_attr "length" "7")
14885    (set_attr "memory" "load")
14886    (set_attr "imm_disp" "false")])
14888 (define_insn "*add_tp_di"
14889   [(set (match_operand:DI 0 "register_operand" "=r")
14890         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14891                  (match_operand:DI 1 "register_operand" "0")))
14892    (clobber (reg:CC FLAGS_REG))]
14893   "TARGET_64BIT"
14894   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14895   [(set_attr "type" "alu")
14896    (set_attr "modrm" "0")
14897    (set_attr "length" "7")
14898    (set_attr "memory" "load")
14899    (set_attr "imm_disp" "false")])
14901 ;; GNU2 TLS patterns can be split.
14903 (define_expand "tls_dynamic_gnu2_32"
14904   [(set (match_dup 3)
14905         (plus:SI (match_operand:SI 2 "register_operand" "")
14906                  (const:SI
14907                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14908                              UNSPEC_TLSDESC))))
14909    (parallel
14910     [(set (match_operand:SI 0 "register_operand" "")
14911           (unspec:SI [(match_dup 1) (match_dup 3)
14912                       (match_dup 2) (reg:SI SP_REG)]
14913                       UNSPEC_TLSDESC))
14914      (clobber (reg:CC FLAGS_REG))])]
14915   "!TARGET_64BIT && TARGET_GNU2_TLS"
14917   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14918   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14921 (define_insn "*tls_dynamic_lea_32"
14922   [(set (match_operand:SI 0 "register_operand" "=r")
14923         (plus:SI (match_operand:SI 1 "register_operand" "b")
14924                  (const:SI
14925                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14926                               UNSPEC_TLSDESC))))]
14927   "!TARGET_64BIT && TARGET_GNU2_TLS"
14928   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14929   [(set_attr "type" "lea")
14930    (set_attr "mode" "SI")
14931    (set_attr "length" "6")
14932    (set_attr "length_address" "4")])
14934 (define_insn "*tls_dynamic_call_32"
14935   [(set (match_operand:SI 0 "register_operand" "=a")
14936         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14937                     (match_operand:SI 2 "register_operand" "0")
14938                     ;; we have to make sure %ebx still points to the GOT
14939                     (match_operand:SI 3 "register_operand" "b")
14940                     (reg:SI SP_REG)]
14941                    UNSPEC_TLSDESC))
14942    (clobber (reg:CC FLAGS_REG))]
14943   "!TARGET_64BIT && TARGET_GNU2_TLS"
14944   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14945   [(set_attr "type" "call")
14946    (set_attr "length" "2")
14947    (set_attr "length_address" "0")])
14949 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14950   [(set (match_operand:SI 0 "register_operand" "=&a")
14951         (plus:SI
14952          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14953                      (match_operand:SI 4 "" "")
14954                      (match_operand:SI 2 "register_operand" "b")
14955                      (reg:SI SP_REG)]
14956                     UNSPEC_TLSDESC)
14957          (const:SI (unspec:SI
14958                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14959                     UNSPEC_DTPOFF))))
14960    (clobber (reg:CC FLAGS_REG))]
14961   "!TARGET_64BIT && TARGET_GNU2_TLS"
14962   "#"
14963   ""
14964   [(set (match_dup 0) (match_dup 5))]
14966   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14967   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14970 (define_expand "tls_dynamic_gnu2_64"
14971   [(set (match_dup 2)
14972         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14973                    UNSPEC_TLSDESC))
14974    (parallel
14975     [(set (match_operand:DI 0 "register_operand" "")
14976           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14977                      UNSPEC_TLSDESC))
14978      (clobber (reg:CC FLAGS_REG))])]
14979   "TARGET_64BIT && TARGET_GNU2_TLS"
14981   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14982   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14985 (define_insn "*tls_dynamic_lea_64"
14986   [(set (match_operand:DI 0 "register_operand" "=r")
14987         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14988                    UNSPEC_TLSDESC))]
14989   "TARGET_64BIT && TARGET_GNU2_TLS"
14990   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14991   [(set_attr "type" "lea")
14992    (set_attr "mode" "DI")
14993    (set_attr "length" "7")
14994    (set_attr "length_address" "4")])
14996 (define_insn "*tls_dynamic_call_64"
14997   [(set (match_operand:DI 0 "register_operand" "=a")
14998         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14999                     (match_operand:DI 2 "register_operand" "0")
15000                     (reg:DI SP_REG)]
15001                    UNSPEC_TLSDESC))
15002    (clobber (reg:CC FLAGS_REG))]
15003   "TARGET_64BIT && TARGET_GNU2_TLS"
15004   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15005   [(set_attr "type" "call")
15006    (set_attr "length" "2")
15007    (set_attr "length_address" "0")])
15009 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15010   [(set (match_operand:DI 0 "register_operand" "=&a")
15011         (plus:DI
15012          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15013                      (match_operand:DI 3 "" "")
15014                      (reg:DI SP_REG)]
15015                     UNSPEC_TLSDESC)
15016          (const:DI (unspec:DI
15017                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15018                     UNSPEC_DTPOFF))))
15019    (clobber (reg:CC FLAGS_REG))]
15020   "TARGET_64BIT && TARGET_GNU2_TLS"
15021   "#"
15022   ""
15023   [(set (match_dup 0) (match_dup 4))]
15025   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15026   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15031 ;; These patterns match the binary 387 instructions for addM3, subM3,
15032 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15033 ;; SFmode.  The first is the normal insn, the second the same insn but
15034 ;; with one operand a conversion, and the third the same insn but with
15035 ;; the other operand a conversion.  The conversion may be SFmode or
15036 ;; SImode if the target mode DFmode, but only SImode if the target mode
15037 ;; is SFmode.
15039 ;; Gcc is slightly more smart about handling normal two address instructions
15040 ;; so use special patterns for add and mull.
15042 (define_insn "*fop_sf_comm_mixed"
15043   [(set (match_operand:SF 0 "register_operand" "=f,x")
15044         (match_operator:SF 3 "binary_fp_operator"
15045                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15046                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15047   "TARGET_MIX_SSE_I387
15048    && COMMUTATIVE_ARITH_P (operands[3])
15049    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15050   "* return output_387_binary_op (insn, operands);"
15051   [(set (attr "type")
15052         (if_then_else (eq_attr "alternative" "1")
15053            (if_then_else (match_operand:SF 3 "mult_operator" "")
15054               (const_string "ssemul")
15055               (const_string "sseadd"))
15056            (if_then_else (match_operand:SF 3 "mult_operator" "")
15057               (const_string "fmul")
15058               (const_string "fop"))))
15059    (set_attr "mode" "SF")])
15061 (define_insn "*fop_sf_comm_sse"
15062   [(set (match_operand:SF 0 "register_operand" "=x")
15063         (match_operator:SF 3 "binary_fp_operator"
15064                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15065                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15066   "TARGET_SSE_MATH
15067    && COMMUTATIVE_ARITH_P (operands[3])
15068    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15069   "* return output_387_binary_op (insn, operands);"
15070   [(set (attr "type")
15071         (if_then_else (match_operand:SF 3 "mult_operator" "")
15072            (const_string "ssemul")
15073            (const_string "sseadd")))
15074    (set_attr "mode" "SF")])
15076 (define_insn "*fop_sf_comm_i387"
15077   [(set (match_operand:SF 0 "register_operand" "=f")
15078         (match_operator:SF 3 "binary_fp_operator"
15079                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15080                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15081   "TARGET_80387
15082    && COMMUTATIVE_ARITH_P (operands[3])
15083    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15084   "* return output_387_binary_op (insn, operands);"
15085   [(set (attr "type")
15086         (if_then_else (match_operand:SF 3 "mult_operator" "")
15087            (const_string "fmul")
15088            (const_string "fop")))
15089    (set_attr "mode" "SF")])
15091 (define_insn "*fop_sf_1_mixed"
15092   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15093         (match_operator:SF 3 "binary_fp_operator"
15094                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15095                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15096   "TARGET_MIX_SSE_I387
15097    && !COMMUTATIVE_ARITH_P (operands[3])
15098    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15099   "* return output_387_binary_op (insn, operands);"
15100   [(set (attr "type")
15101         (cond [(and (eq_attr "alternative" "2")
15102                     (match_operand:SF 3 "mult_operator" ""))
15103                  (const_string "ssemul")
15104                (and (eq_attr "alternative" "2")
15105                     (match_operand:SF 3 "div_operator" ""))
15106                  (const_string "ssediv")
15107                (eq_attr "alternative" "2")
15108                  (const_string "sseadd")
15109                (match_operand:SF 3 "mult_operator" "")
15110                  (const_string "fmul")
15111                (match_operand:SF 3 "div_operator" "")
15112                  (const_string "fdiv")
15113               ]
15114               (const_string "fop")))
15115    (set_attr "mode" "SF")])
15117 (define_insn "*fop_sf_1_sse"
15118   [(set (match_operand:SF 0 "register_operand" "=x")
15119         (match_operator:SF 3 "binary_fp_operator"
15120                         [(match_operand:SF 1 "register_operand" "0")
15121                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15122   "TARGET_SSE_MATH
15123    && !COMMUTATIVE_ARITH_P (operands[3])"
15124   "* return output_387_binary_op (insn, operands);"
15125   [(set (attr "type")
15126         (cond [(match_operand:SF 3 "mult_operator" "")
15127                  (const_string "ssemul")
15128                (match_operand:SF 3 "div_operator" "")
15129                  (const_string "ssediv")
15130               ]
15131               (const_string "sseadd")))
15132    (set_attr "mode" "SF")])
15134 ;; This pattern is not fully shadowed by the pattern above.
15135 (define_insn "*fop_sf_1_i387"
15136   [(set (match_operand:SF 0 "register_operand" "=f,f")
15137         (match_operator:SF 3 "binary_fp_operator"
15138                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15139                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15140   "TARGET_80387 && !TARGET_SSE_MATH
15141    && !COMMUTATIVE_ARITH_P (operands[3])
15142    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15143   "* return output_387_binary_op (insn, operands);"
15144   [(set (attr "type")
15145         (cond [(match_operand:SF 3 "mult_operator" "")
15146                  (const_string "fmul")
15147                (match_operand:SF 3 "div_operator" "")
15148                  (const_string "fdiv")
15149               ]
15150               (const_string "fop")))
15151    (set_attr "mode" "SF")])
15153 ;; ??? Add SSE splitters for these!
15154 (define_insn "*fop_sf_2<mode>_i387"
15155   [(set (match_operand:SF 0 "register_operand" "=f,f")
15156         (match_operator:SF 3 "binary_fp_operator"
15157           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15158            (match_operand:SF 2 "register_operand" "0,0")]))]
15159   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15160   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15161   [(set (attr "type")
15162         (cond [(match_operand:SF 3 "mult_operator" "")
15163                  (const_string "fmul")
15164                (match_operand:SF 3 "div_operator" "")
15165                  (const_string "fdiv")
15166               ]
15167               (const_string "fop")))
15168    (set_attr "fp_int_src" "true")
15169    (set_attr "mode" "<MODE>")])
15171 (define_insn "*fop_sf_3<mode>_i387"
15172   [(set (match_operand:SF 0 "register_operand" "=f,f")
15173         (match_operator:SF 3 "binary_fp_operator"
15174           [(match_operand:SF 1 "register_operand" "0,0")
15175            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15176   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15177   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15178   [(set (attr "type")
15179         (cond [(match_operand:SF 3 "mult_operator" "")
15180                  (const_string "fmul")
15181                (match_operand:SF 3 "div_operator" "")
15182                  (const_string "fdiv")
15183               ]
15184               (const_string "fop")))
15185    (set_attr "fp_int_src" "true")
15186    (set_attr "mode" "<MODE>")])
15188 (define_insn "*fop_df_comm_mixed"
15189   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15190         (match_operator:DF 3 "binary_fp_operator"
15191                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15192                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15193   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15194    && COMMUTATIVE_ARITH_P (operands[3])
15195    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15196   "* return output_387_binary_op (insn, operands);"
15197   [(set (attr "type")
15198         (if_then_else (eq_attr "alternative" "1")
15199            (if_then_else (match_operand:DF 3 "mult_operator" "")
15200               (const_string "ssemul")
15201               (const_string "sseadd"))
15202            (if_then_else (match_operand:DF 3 "mult_operator" "")
15203               (const_string "fmul")
15204               (const_string "fop"))))
15205    (set_attr "mode" "DF")])
15207 (define_insn "*fop_df_comm_sse"
15208   [(set (match_operand:DF 0 "register_operand" "=Y")
15209         (match_operator:DF 3 "binary_fp_operator"
15210                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15211                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15212   "TARGET_SSE2 && TARGET_SSE_MATH
15213    && COMMUTATIVE_ARITH_P (operands[3])
15214    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15215   "* return output_387_binary_op (insn, operands);"
15216   [(set (attr "type")
15217         (if_then_else (match_operand:DF 3 "mult_operator" "")
15218            (const_string "ssemul")
15219            (const_string "sseadd")))
15220    (set_attr "mode" "DF")])
15222 (define_insn "*fop_df_comm_i387"
15223   [(set (match_operand:DF 0 "register_operand" "=f")
15224         (match_operator:DF 3 "binary_fp_operator"
15225                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15226                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15227   "TARGET_80387
15228    && COMMUTATIVE_ARITH_P (operands[3])
15229    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15230   "* return output_387_binary_op (insn, operands);"
15231   [(set (attr "type")
15232         (if_then_else (match_operand:DF 3 "mult_operator" "")
15233            (const_string "fmul")
15234            (const_string "fop")))
15235    (set_attr "mode" "DF")])
15237 (define_insn "*fop_df_1_mixed"
15238   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15239         (match_operator:DF 3 "binary_fp_operator"
15240                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15241                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15242   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15243    && !COMMUTATIVE_ARITH_P (operands[3])
15244    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15245   "* return output_387_binary_op (insn, operands);"
15246   [(set (attr "type")
15247         (cond [(and (eq_attr "alternative" "2")
15248                     (match_operand:DF 3 "mult_operator" ""))
15249                  (const_string "ssemul")
15250                (and (eq_attr "alternative" "2")
15251                     (match_operand:DF 3 "div_operator" ""))
15252                  (const_string "ssediv")
15253                (eq_attr "alternative" "2")
15254                  (const_string "sseadd")
15255                (match_operand:DF 3 "mult_operator" "")
15256                  (const_string "fmul")
15257                (match_operand:DF 3 "div_operator" "")
15258                  (const_string "fdiv")
15259               ]
15260               (const_string "fop")))
15261    (set_attr "mode" "DF")])
15263 (define_insn "*fop_df_1_sse"
15264   [(set (match_operand:DF 0 "register_operand" "=Y")
15265         (match_operator:DF 3 "binary_fp_operator"
15266                         [(match_operand:DF 1 "register_operand" "0")
15267                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15268   "TARGET_SSE2 && TARGET_SSE_MATH
15269    && !COMMUTATIVE_ARITH_P (operands[3])"
15270   "* return output_387_binary_op (insn, operands);"
15271   [(set_attr "mode" "DF")
15272    (set (attr "type")
15273         (cond [(match_operand:DF 3 "mult_operator" "")
15274                  (const_string "ssemul")
15275                (match_operand:DF 3 "div_operator" "")
15276                  (const_string "ssediv")
15277               ]
15278               (const_string "sseadd")))])
15280 ;; This pattern is not fully shadowed by the pattern above.
15281 (define_insn "*fop_df_1_i387"
15282   [(set (match_operand:DF 0 "register_operand" "=f,f")
15283         (match_operator:DF 3 "binary_fp_operator"
15284                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15285                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15286   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15287    && !COMMUTATIVE_ARITH_P (operands[3])
15288    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15289   "* return 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 "mode" "DF")])
15299 ;; ??? Add SSE splitters for these!
15300 (define_insn "*fop_df_2<mode>_i387"
15301   [(set (match_operand:DF 0 "register_operand" "=f,f")
15302         (match_operator:DF 3 "binary_fp_operator"
15303            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15304             (match_operand:DF 2 "register_operand" "0,0")]))]
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_3<mode>_i387"
15319   [(set (match_operand:DF 0 "register_operand" "=f,f")
15320         (match_operator:DF 3 "binary_fp_operator"
15321            [(match_operand:DF 1 "register_operand" "0,0")
15322             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15323   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15324    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15325   "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
15334    (set_attr "mode" "<MODE>")])
15336 (define_insn "*fop_df_4_i387"
15337   [(set (match_operand:DF 0 "register_operand" "=f,f")
15338         (match_operator:DF 3 "binary_fp_operator"
15339            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15340             (match_operand:DF 2 "register_operand" "0,f")]))]
15341   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15342    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15343   "* return output_387_binary_op (insn, operands);"
15344   [(set (attr "type")
15345         (cond [(match_operand:DF 3 "mult_operator" "")
15346                  (const_string "fmul")
15347                (match_operand:DF 3 "div_operator" "")
15348                  (const_string "fdiv")
15349               ]
15350               (const_string "fop")))
15351    (set_attr "mode" "SF")])
15353 (define_insn "*fop_df_5_i387"
15354   [(set (match_operand:DF 0 "register_operand" "=f,f")
15355         (match_operator:DF 3 "binary_fp_operator"
15356           [(match_operand:DF 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_df_6_i387"
15371   [(set (match_operand:DF 0 "register_operand" "=f,f")
15372         (match_operator:DF 3 "binary_fp_operator"
15373           [(float_extend:DF
15374             (match_operand:SF 1 "register_operand" "0,f"))
15375            (float_extend:DF
15376             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15377   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15378   "* return output_387_binary_op (insn, operands);"
15379   [(set (attr "type")
15380         (cond [(match_operand:DF 3 "mult_operator" "")
15381                  (const_string "fmul")
15382                (match_operand:DF 3 "div_operator" "")
15383                  (const_string "fdiv")
15384               ]
15385               (const_string "fop")))
15386    (set_attr "mode" "SF")])
15388 (define_insn "*fop_xf_comm_i387"
15389   [(set (match_operand:XF 0 "register_operand" "=f")
15390         (match_operator:XF 3 "binary_fp_operator"
15391                         [(match_operand:XF 1 "register_operand" "%0")
15392                          (match_operand:XF 2 "register_operand" "f")]))]
15393   "TARGET_80387
15394    && COMMUTATIVE_ARITH_P (operands[3])"
15395   "* return output_387_binary_op (insn, operands);"
15396   [(set (attr "type")
15397         (if_then_else (match_operand:XF 3 "mult_operator" "")
15398            (const_string "fmul")
15399            (const_string "fop")))
15400    (set_attr "mode" "XF")])
15402 (define_insn "*fop_xf_1_i387"
15403   [(set (match_operand:XF 0 "register_operand" "=f,f")
15404         (match_operator:XF 3 "binary_fp_operator"
15405                         [(match_operand:XF 1 "register_operand" "0,f")
15406                          (match_operand:XF 2 "register_operand" "f,0")]))]
15407   "TARGET_80387
15408    && !COMMUTATIVE_ARITH_P (operands[3])"
15409   "* return output_387_binary_op (insn, operands);"
15410   [(set (attr "type")
15411         (cond [(match_operand:XF 3 "mult_operator" "")
15412                  (const_string "fmul")
15413                (match_operand:XF 3 "div_operator" "")
15414                  (const_string "fdiv")
15415               ]
15416               (const_string "fop")))
15417    (set_attr "mode" "XF")])
15419 (define_insn "*fop_xf_2<mode>_i387"
15420   [(set (match_operand:XF 0 "register_operand" "=f,f")
15421         (match_operator:XF 3 "binary_fp_operator"
15422            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15423             (match_operand:XF 2 "register_operand" "0,0")]))]
15424   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15425   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15426   [(set (attr "type")
15427         (cond [(match_operand:XF 3 "mult_operator" "")
15428                  (const_string "fmul")
15429                (match_operand:XF 3 "div_operator" "")
15430                  (const_string "fdiv")
15431               ]
15432               (const_string "fop")))
15433    (set_attr "fp_int_src" "true")
15434    (set_attr "mode" "<MODE>")])
15436 (define_insn "*fop_xf_3<mode>_i387"
15437   [(set (match_operand:XF 0 "register_operand" "=f,f")
15438         (match_operator:XF 3 "binary_fp_operator"
15439           [(match_operand:XF 1 "register_operand" "0,0")
15440            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15441   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15442   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15443   [(set (attr "type")
15444         (cond [(match_operand:XF 3 "mult_operator" "")
15445                  (const_string "fmul")
15446                (match_operand:XF 3 "div_operator" "")
15447                  (const_string "fdiv")
15448               ]
15449               (const_string "fop")))
15450    (set_attr "fp_int_src" "true")
15451    (set_attr "mode" "<MODE>")])
15453 (define_insn "*fop_xf_4_i387"
15454   [(set (match_operand:XF 0 "register_operand" "=f,f")
15455         (match_operator:XF 3 "binary_fp_operator"
15456            [(float_extend:XF
15457               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15458             (match_operand:XF 2 "register_operand" "0,f")]))]
15459   "TARGET_80387"
15460   "* return output_387_binary_op (insn, operands);"
15461   [(set (attr "type")
15462         (cond [(match_operand:XF 3 "mult_operator" "")
15463                  (const_string "fmul")
15464                (match_operand:XF 3 "div_operator" "")
15465                  (const_string "fdiv")
15466               ]
15467               (const_string "fop")))
15468    (set_attr "mode" "SF")])
15470 (define_insn "*fop_xf_5_i387"
15471   [(set (match_operand:XF 0 "register_operand" "=f,f")
15472         (match_operator:XF 3 "binary_fp_operator"
15473           [(match_operand:XF 1 "register_operand" "0,f")
15474            (float_extend:XF
15475              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15476   "TARGET_80387"
15477   "* return output_387_binary_op (insn, operands);"
15478   [(set (attr "type")
15479         (cond [(match_operand:XF 3 "mult_operator" "")
15480                  (const_string "fmul")
15481                (match_operand:XF 3 "div_operator" "")
15482                  (const_string "fdiv")
15483               ]
15484               (const_string "fop")))
15485    (set_attr "mode" "SF")])
15487 (define_insn "*fop_xf_6_i387"
15488   [(set (match_operand:XF 0 "register_operand" "=f,f")
15489         (match_operator:XF 3 "binary_fp_operator"
15490           [(float_extend:XF
15491              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15492            (float_extend:XF
15493              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15494   "TARGET_80387"
15495   "* return output_387_binary_op (insn, operands);"
15496   [(set (attr "type")
15497         (cond [(match_operand:XF 3 "mult_operator" "")
15498                  (const_string "fmul")
15499                (match_operand:XF 3 "div_operator" "")
15500                  (const_string "fdiv")
15501               ]
15502               (const_string "fop")))
15503    (set_attr "mode" "SF")])
15505 (define_split
15506   [(set (match_operand 0 "register_operand" "")
15507         (match_operator 3 "binary_fp_operator"
15508            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15509             (match_operand 2 "register_operand" "")]))]
15510   "TARGET_80387 && reload_completed
15511    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15512   [(const_int 0)]
15514   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15515   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15516   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15517                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15518                                           GET_MODE (operands[3]),
15519                                           operands[4],
15520                                           operands[2])));
15521   ix86_free_from_memory (GET_MODE (operands[1]));
15522   DONE;
15525 (define_split
15526   [(set (match_operand 0 "register_operand" "")
15527         (match_operator 3 "binary_fp_operator"
15528            [(match_operand 1 "register_operand" "")
15529             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15530   "TARGET_80387 && reload_completed
15531    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15532   [(const_int 0)]
15534   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15535   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15536   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15537                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15538                                           GET_MODE (operands[3]),
15539                                           operands[1],
15540                                           operands[4])));
15541   ix86_free_from_memory (GET_MODE (operands[2]));
15542   DONE;
15545 ;; FPU special functions.
15547 ;; This pattern implements a no-op XFmode truncation for
15548 ;; all fancy i386 XFmode math functions.
15550 (define_insn "truncxf<mode>2_i387_noop_unspec"
15551   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15552         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15553         UNSPEC_TRUNC_NOOP))]
15554   "TARGET_USE_FANCY_MATH_387"
15555   "* return output_387_reg_move (insn, operands);"
15556   [(set_attr "type" "fmov")
15557    (set_attr "mode" "<MODE>")])
15559 (define_insn "sqrtxf2"
15560   [(set (match_operand:XF 0 "register_operand" "=f")
15561         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15562   "TARGET_USE_FANCY_MATH_387"
15563   "fsqrt"
15564   [(set_attr "type" "fpspc")
15565    (set_attr "mode" "XF")
15566    (set_attr "athlon_decode" "direct")])
15568 (define_insn "sqrt_extend<mode>xf2_i387"
15569   [(set (match_operand:XF 0 "register_operand" "=f")
15570         (sqrt:XF
15571           (float_extend:XF
15572             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15573   "TARGET_USE_FANCY_MATH_387"
15574   "fsqrt"
15575   [(set_attr "type" "fpspc")
15576    (set_attr "mode" "XF")
15577    (set_attr "athlon_decode" "direct")])
15579 (define_insn "*sqrt<mode>2_sse"
15580   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15581         (sqrt:SSEMODEF
15582           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15583   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15584   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15585   [(set_attr "type" "sse")
15586    (set_attr "mode" "<MODE>")
15587    (set_attr "athlon_decode" "*")])
15589 (define_expand "sqrt<mode>2"
15590   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15591         (sqrt:X87MODEF12
15592           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15593   "TARGET_USE_FANCY_MATH_387
15594    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15596   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15597     {
15598       rtx op0 = gen_reg_rtx (XFmode);
15599       rtx op1 = force_reg (<MODE>mode, operands[1]);
15601       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15602       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15603       DONE;
15604    }
15607 (define_insn "fpremxf4_i387"
15608   [(set (match_operand:XF 0 "register_operand" "=f")
15609         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15610                     (match_operand:XF 3 "register_operand" "1")]
15611                    UNSPEC_FPREM_F))
15612    (set (match_operand:XF 1 "register_operand" "=u")
15613         (unspec:XF [(match_dup 2) (match_dup 3)]
15614                    UNSPEC_FPREM_U))
15615    (set (reg:CCFP FPSR_REG)
15616         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15617   "TARGET_USE_FANCY_MATH_387"
15618   "fprem"
15619   [(set_attr "type" "fpspc")
15620    (set_attr "mode" "XF")])
15622 (define_expand "fmodxf3"
15623   [(use (match_operand:XF 0 "register_operand" ""))
15624    (use (match_operand:XF 1 "register_operand" ""))
15625    (use (match_operand:XF 2 "register_operand" ""))]
15626   "TARGET_USE_FANCY_MATH_387"
15628   rtx label = gen_label_rtx ();
15630   emit_label (label);
15632   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15633                                 operands[1], operands[2]));
15634   ix86_emit_fp_unordered_jump (label);
15636   emit_move_insn (operands[0], operands[1]);
15637   DONE;
15640 (define_expand "fmod<mode>3"
15641   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15642    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15643    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15644   "TARGET_USE_FANCY_MATH_387"
15646   rtx label = gen_label_rtx ();
15648   rtx op1 = gen_reg_rtx (XFmode);
15649   rtx op2 = gen_reg_rtx (XFmode);
15651   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15652   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15654   emit_label (label);
15655   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15656   ix86_emit_fp_unordered_jump (label);
15658   /* Truncate the result properly for strict SSE math.  */
15659   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15660       && !TARGET_MIX_SSE_I387)
15661     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15662   else
15663     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15665   DONE;
15668 (define_insn "fprem1xf4_i387"
15669   [(set (match_operand:XF 0 "register_operand" "=f")
15670         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15671                     (match_operand:XF 3 "register_operand" "1")]
15672                    UNSPEC_FPREM1_F))
15673    (set (match_operand:XF 1 "register_operand" "=u")
15674         (unspec:XF [(match_dup 2) (match_dup 3)]
15675                    UNSPEC_FPREM1_U))
15676    (set (reg:CCFP FPSR_REG)
15677         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15678   "TARGET_USE_FANCY_MATH_387"
15679   "fprem1"
15680   [(set_attr "type" "fpspc")
15681    (set_attr "mode" "XF")])
15683 (define_expand "remainderxf3"
15684   [(use (match_operand:XF 0 "register_operand" ""))
15685    (use (match_operand:XF 1 "register_operand" ""))
15686    (use (match_operand:XF 2 "register_operand" ""))]
15687   "TARGET_USE_FANCY_MATH_387"
15689   rtx label = gen_label_rtx ();
15691   emit_label (label);
15693   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15694                                  operands[1], operands[2]));
15695   ix86_emit_fp_unordered_jump (label);
15697   emit_move_insn (operands[0], operands[1]);
15698   DONE;
15701 (define_expand "remainder<mode>3"
15702   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15703    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15704    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15705   "TARGET_USE_FANCY_MATH_387"
15707   rtx label = gen_label_rtx ();
15709   rtx op1 = gen_reg_rtx (XFmode);
15710   rtx op2 = gen_reg_rtx (XFmode);
15712   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15713   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15715   emit_label (label);
15717   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15718   ix86_emit_fp_unordered_jump (label);
15720   /* Truncate the result properly for strict SSE math.  */
15721   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15722       && !TARGET_MIX_SSE_I387)
15723     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15724   else
15725     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15727   DONE;
15730 (define_insn "*sinxf2_i387"
15731   [(set (match_operand:XF 0 "register_operand" "=f")
15732         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15733   "TARGET_USE_FANCY_MATH_387
15734    && flag_unsafe_math_optimizations"
15735   "fsin"
15736   [(set_attr "type" "fpspc")
15737    (set_attr "mode" "XF")])
15739 (define_insn "*sin_extend<mode>xf2_i387"
15740   [(set (match_operand:XF 0 "register_operand" "=f")
15741         (unspec:XF [(float_extend:XF
15742                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
15743                    UNSPEC_SIN))]
15744   "TARGET_USE_FANCY_MATH_387
15745    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15746        || TARGET_MIX_SSE_I387)
15747    && flag_unsafe_math_optimizations"
15748   "fsin"
15749   [(set_attr "type" "fpspc")
15750    (set_attr "mode" "XF")])
15752 (define_insn "*cosxf2_i387"
15753   [(set (match_operand:XF 0 "register_operand" "=f")
15754         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15755   "TARGET_USE_FANCY_MATH_387
15756    && flag_unsafe_math_optimizations"
15757   "fcos"
15758   [(set_attr "type" "fpspc")
15759    (set_attr "mode" "XF")])
15761 (define_insn "*cos_extend<mode>xf2_i387"
15762   [(set (match_operand:XF 0 "register_operand" "=f")
15763         (unspec:XF [(float_extend:XF
15764                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
15765                    UNSPEC_COS))]
15766   "TARGET_USE_FANCY_MATH_387
15767    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15768        || TARGET_MIX_SSE_I387)
15769    && flag_unsafe_math_optimizations"
15770   "fcos"
15771   [(set_attr "type" "fpspc")
15772    (set_attr "mode" "XF")])
15774 ;; When sincos pattern is defined, sin and cos builtin functions will be
15775 ;; expanded to sincos pattern with one of its outputs left unused.
15776 ;; CSE pass will figure out if two sincos patterns can be combined,
15777 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15778 ;; depending on the unused output.
15780 (define_insn "sincosxf3"
15781   [(set (match_operand:XF 0 "register_operand" "=f")
15782         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15783                    UNSPEC_SINCOS_COS))
15784    (set (match_operand:XF 1 "register_operand" "=u")
15785         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15786   "TARGET_USE_FANCY_MATH_387
15787    && flag_unsafe_math_optimizations"
15788   "fsincos"
15789   [(set_attr "type" "fpspc")
15790    (set_attr "mode" "XF")])
15792 (define_split
15793   [(set (match_operand:XF 0 "register_operand" "")
15794         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15795                    UNSPEC_SINCOS_COS))
15796    (set (match_operand:XF 1 "register_operand" "")
15797         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15798   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15799    && !reload_completed && !reload_in_progress"
15800   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15801   "")
15803 (define_split
15804   [(set (match_operand:XF 0 "register_operand" "")
15805         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15806                    UNSPEC_SINCOS_COS))
15807    (set (match_operand:XF 1 "register_operand" "")
15808         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15809   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15810    && !reload_completed && !reload_in_progress"
15811   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15812   "")
15814 (define_insn "sincos_extend<mode>xf3_i387"
15815   [(set (match_operand:XF 0 "register_operand" "=f")
15816         (unspec:XF [(float_extend:XF
15817                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
15818                    UNSPEC_SINCOS_COS))
15819    (set (match_operand:XF 1 "register_operand" "=u")
15820         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15821   "TARGET_USE_FANCY_MATH_387
15822    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15823        || TARGET_MIX_SSE_I387)
15824    && flag_unsafe_math_optimizations"
15825   "fsincos"
15826   [(set_attr "type" "fpspc")
15827    (set_attr "mode" "XF")])
15829 (define_split
15830   [(set (match_operand:XF 0 "register_operand" "")
15831         (unspec:XF [(float_extend:XF
15832                       (match_operand:X87MODEF12 2 "register_operand" ""))]
15833                    UNSPEC_SINCOS_COS))
15834    (set (match_operand:XF 1 "register_operand" "")
15835         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15836   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15837    && !reload_completed && !reload_in_progress"
15838   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15839   "")
15841 (define_split
15842   [(set (match_operand:XF 0 "register_operand" "")
15843         (unspec:XF [(float_extend:XF
15844                       (match_operand:X87MODEF12 2 "register_operand" ""))]
15845                    UNSPEC_SINCOS_COS))
15846    (set (match_operand:XF 1 "register_operand" "")
15847         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15848   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15849    && !reload_completed && !reload_in_progress"
15850   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15851   "")
15853 (define_expand "sincos<mode>3"
15854   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15855    (use (match_operand:X87MODEF12 1 "register_operand" ""))
15856    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15857   "TARGET_USE_FANCY_MATH_387
15858    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15859        || TARGET_MIX_SSE_I387)
15860    && flag_unsafe_math_optimizations"
15862   rtx op0 = gen_reg_rtx (XFmode);
15863   rtx op1 = gen_reg_rtx (XFmode);
15865   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15866   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15867   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15868   DONE;
15871 (define_insn "fptanxf4_i387"
15872   [(set (match_operand:XF 0 "register_operand" "=f")
15873         (match_operand:XF 3 "const_double_operand" "F"))
15874    (set (match_operand:XF 1 "register_operand" "=u")
15875         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15876                    UNSPEC_TAN))]
15877   "TARGET_USE_FANCY_MATH_387
15878    && flag_unsafe_math_optimizations
15879    && standard_80387_constant_p (operands[3]) == 2"
15880   "fptan"
15881   [(set_attr "type" "fpspc")
15882    (set_attr "mode" "XF")])
15884 (define_insn "fptan_extend<mode>xf4_i387"
15885   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15886         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
15887    (set (match_operand:XF 1 "register_operand" "=u")
15888         (unspec:XF [(float_extend:XF
15889                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
15890                    UNSPEC_TAN))]
15891   "TARGET_USE_FANCY_MATH_387
15892    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15893        || TARGET_MIX_SSE_I387)
15894    && flag_unsafe_math_optimizations
15895    && standard_80387_constant_p (operands[3]) == 2"
15896   "fptan"
15897   [(set_attr "type" "fpspc")
15898    (set_attr "mode" "XF")])
15900 (define_expand "tanxf2"
15901   [(use (match_operand:XF 0 "register_operand" ""))
15902    (use (match_operand:XF 1 "register_operand" ""))]
15903   "TARGET_USE_FANCY_MATH_387
15904    && flag_unsafe_math_optimizations"
15906   rtx one = gen_reg_rtx (XFmode);
15907   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15909   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15910   DONE;
15913 (define_expand "tan<mode>2"
15914   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15915    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
15916   "TARGET_USE_FANCY_MATH_387
15917    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15918        || TARGET_MIX_SSE_I387)
15919    && flag_unsafe_math_optimizations"
15921   rtx op0 = gen_reg_rtx (XFmode);
15923   rtx one = gen_reg_rtx (<MODE>mode);
15924   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15926   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15927                                              operands[1], op2));
15928   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15929   DONE;
15932 (define_insn "*fpatanxf3_i387"
15933   [(set (match_operand:XF 0 "register_operand" "=f")
15934         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15935                     (match_operand:XF 2 "register_operand" "u")]
15936                    UNSPEC_FPATAN))
15937    (clobber (match_scratch:XF 3 "=2"))]
15938   "TARGET_USE_FANCY_MATH_387
15939    && flag_unsafe_math_optimizations"
15940   "fpatan"
15941   [(set_attr "type" "fpspc")
15942    (set_attr "mode" "XF")])
15944 (define_insn "fpatan_extend<mode>xf3_i387"
15945   [(set (match_operand:XF 0 "register_operand" "=f")
15946         (unspec:XF [(float_extend:XF
15947                       (match_operand:X87MODEF12 1 "register_operand" "0"))
15948                     (float_extend:XF
15949                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
15950                    UNSPEC_FPATAN))
15951    (clobber (match_scratch:XF 3 "=2"))]
15952   "TARGET_USE_FANCY_MATH_387
15953    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15954        || TARGET_MIX_SSE_I387)
15955    && flag_unsafe_math_optimizations"
15956   "fpatan"
15957   [(set_attr "type" "fpspc")
15958    (set_attr "mode" "XF")])
15960 (define_expand "atan2xf3"
15961   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15962                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
15963                                (match_operand:XF 1 "register_operand" "")]
15964                               UNSPEC_FPATAN))
15965               (clobber (match_scratch:XF 3 ""))])]
15966   "TARGET_USE_FANCY_MATH_387
15967    && flag_unsafe_math_optimizations"
15968   "")
15970 (define_expand "atan2<mode>3"
15971   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15972    (use (match_operand:X87MODEF12 1 "register_operand" ""))
15973    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15974   "TARGET_USE_FANCY_MATH_387
15975    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15976        || TARGET_MIX_SSE_I387)
15977    && flag_unsafe_math_optimizations"
15979   rtx op0 = gen_reg_rtx (XFmode);
15981   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15982   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15983   DONE;
15986 (define_expand "atanxf2"
15987   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15988                    (unspec:XF [(match_dup 2)
15989                                (match_operand:XF 1 "register_operand" "")]
15990                               UNSPEC_FPATAN))
15991               (clobber (match_scratch:XF 3 ""))])]
15992   "TARGET_USE_FANCY_MATH_387
15993    && flag_unsafe_math_optimizations"
15995   operands[2] = gen_reg_rtx (XFmode);
15996   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15999 (define_expand "atan<mode>2"
16000   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16001    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16002   "TARGET_USE_FANCY_MATH_387
16003    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16004        || TARGET_MIX_SSE_I387)
16005    && flag_unsafe_math_optimizations"
16007   rtx op0 = gen_reg_rtx (XFmode);
16009   rtx op2 = gen_reg_rtx (<MODE>mode);
16010   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16012   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16013   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16014   DONE;
16017 (define_expand "asinxf2"
16018   [(set (match_dup 2)
16019         (mult:XF (match_operand:XF 1 "register_operand" "")
16020                  (match_dup 1)))
16021    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16022    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16023    (parallel [(set (match_operand:XF 0 "register_operand" "")
16024                    (unspec:XF [(match_dup 5) (match_dup 1)]
16025                               UNSPEC_FPATAN))
16026               (clobber (match_scratch:XF 6 ""))])]
16027   "TARGET_USE_FANCY_MATH_387
16028    && flag_unsafe_math_optimizations && !optimize_size"
16030   int i;
16032   for (i = 2; i < 6; i++)
16033     operands[i] = gen_reg_rtx (XFmode);
16035   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16038 (define_expand "asin<mode>2"
16039   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16040    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16041  "TARGET_USE_FANCY_MATH_387
16042    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16043        || TARGET_MIX_SSE_I387)
16044    && flag_unsafe_math_optimizations && !optimize_size"
16046   rtx op0 = gen_reg_rtx (XFmode);
16047   rtx op1 = gen_reg_rtx (XFmode);
16049   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16050   emit_insn (gen_asinxf2 (op0, op1));
16051   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16052   DONE;
16055 (define_expand "acosxf2"
16056   [(set (match_dup 2)
16057         (mult:XF (match_operand:XF 1 "register_operand" "")
16058                  (match_dup 1)))
16059    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16060    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16061    (parallel [(set (match_operand:XF 0 "register_operand" "")
16062                    (unspec:XF [(match_dup 1) (match_dup 5)]
16063                               UNSPEC_FPATAN))
16064               (clobber (match_scratch:XF 6 ""))])]
16065   "TARGET_USE_FANCY_MATH_387
16066    && flag_unsafe_math_optimizations && !optimize_size"
16068   int i;
16070   for (i = 2; i < 6; i++)
16071     operands[i] = gen_reg_rtx (XFmode);
16073   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16076 (define_expand "acos<mode>2"
16077   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16078    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16079  "TARGET_USE_FANCY_MATH_387
16080    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16081        || TARGET_MIX_SSE_I387)
16082    && flag_unsafe_math_optimizations && !optimize_size"
16084   rtx op0 = gen_reg_rtx (XFmode);
16085   rtx op1 = gen_reg_rtx (XFmode);
16087   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16088   emit_insn (gen_acosxf2 (op0, op1));
16089   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16090   DONE;
16093 (define_insn "fyl2xxf3_i387"
16094   [(set (match_operand:XF 0 "register_operand" "=f")
16095         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16096                     (match_operand:XF 2 "register_operand" "u")]
16097                    UNSPEC_FYL2X))
16098    (clobber (match_scratch:XF 3 "=2"))]
16099   "TARGET_USE_FANCY_MATH_387
16100    && flag_unsafe_math_optimizations"
16101   "fyl2x"
16102   [(set_attr "type" "fpspc")
16103    (set_attr "mode" "XF")])
16105 (define_insn "fyl2x_extend<mode>xf3_i387"
16106   [(set (match_operand:XF 0 "register_operand" "=f")
16107         (unspec:XF [(float_extend:XF
16108                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16109                     (match_operand:XF 2 "register_operand" "u")]
16110                    UNSPEC_FYL2X))
16111    (clobber (match_scratch:XF 3 "=2"))]
16112   "TARGET_USE_FANCY_MATH_387
16113    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16114        || TARGET_MIX_SSE_I387)
16115    && flag_unsafe_math_optimizations"
16116   "fyl2x"
16117   [(set_attr "type" "fpspc")
16118    (set_attr "mode" "XF")])
16120 (define_expand "logxf2"
16121   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16122                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16123                                (match_dup 2)] UNSPEC_FYL2X))
16124               (clobber (match_scratch:XF 3 ""))])]
16125   "TARGET_USE_FANCY_MATH_387
16126    && flag_unsafe_math_optimizations"
16128   operands[2] = gen_reg_rtx (XFmode);
16129   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16132 (define_expand "log<mode>2"
16133   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16134    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16135   "TARGET_USE_FANCY_MATH_387
16136    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16137        || TARGET_MIX_SSE_I387)
16138    && flag_unsafe_math_optimizations"
16140   rtx op0 = gen_reg_rtx (XFmode);
16142   rtx op2 = gen_reg_rtx (XFmode);
16143   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16145   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16146   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16147   DONE;
16150 (define_expand "log10xf2"
16151   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16152                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16153                                (match_dup 2)] UNSPEC_FYL2X))
16154               (clobber (match_scratch:XF 3 ""))])]
16155   "TARGET_USE_FANCY_MATH_387
16156    && flag_unsafe_math_optimizations"
16158   operands[2] = gen_reg_rtx (XFmode);
16159   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16162 (define_expand "log10<mode>2"
16163   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16164    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16165   "TARGET_USE_FANCY_MATH_387
16166    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16167        || TARGET_MIX_SSE_I387)
16168    && flag_unsafe_math_optimizations"
16170   rtx op0 = gen_reg_rtx (XFmode);
16172   rtx op2 = gen_reg_rtx (XFmode);
16173   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16175   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16176   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16177   DONE;
16180 (define_expand "log2xf2"
16181   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16182                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16183                                (match_dup 2)] UNSPEC_FYL2X))
16184               (clobber (match_scratch:XF 3 ""))])]
16185   "TARGET_USE_FANCY_MATH_387
16186    && flag_unsafe_math_optimizations"
16188   operands[2] = gen_reg_rtx (XFmode);
16189   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16192 (define_expand "log2<mode>2"
16193   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16194    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16195   "TARGET_USE_FANCY_MATH_387
16196    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16197        || TARGET_MIX_SSE_I387)
16198    && flag_unsafe_math_optimizations"
16200   rtx op0 = gen_reg_rtx (XFmode);
16202   rtx op2 = gen_reg_rtx (XFmode);
16203   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16205   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16206   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16207   DONE;
16210 (define_insn "fyl2xp1xf3_i387"
16211   [(set (match_operand:XF 0 "register_operand" "=f")
16212         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16213                     (match_operand:XF 2 "register_operand" "u")]
16214                    UNSPEC_FYL2XP1))
16215    (clobber (match_scratch:XF 3 "=2"))]
16216   "TARGET_USE_FANCY_MATH_387
16217    && flag_unsafe_math_optimizations"
16218   "fyl2xp1"
16219   [(set_attr "type" "fpspc")
16220    (set_attr "mode" "XF")])
16222 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16223   [(set (match_operand:XF 0 "register_operand" "=f")
16224         (unspec:XF [(float_extend:XF
16225                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16226                     (match_operand:XF 2 "register_operand" "u")]
16227                    UNSPEC_FYL2XP1))
16228    (clobber (match_scratch:XF 3 "=2"))]
16229   "TARGET_USE_FANCY_MATH_387
16230    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16231        || TARGET_MIX_SSE_I387)
16232    && flag_unsafe_math_optimizations"
16233   "fyl2xp1"
16234   [(set_attr "type" "fpspc")
16235    (set_attr "mode" "XF")])
16237 (define_expand "log1pxf2"
16238   [(use (match_operand:XF 0 "register_operand" ""))
16239    (use (match_operand:XF 1 "register_operand" ""))]
16240   "TARGET_USE_FANCY_MATH_387
16241    && flag_unsafe_math_optimizations && !optimize_size"
16243   ix86_emit_i387_log1p (operands[0], operands[1]);
16244   DONE;
16247 (define_expand "log1p<mode>2"
16248   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16249    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16250   "TARGET_USE_FANCY_MATH_387
16251    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16252        || TARGET_MIX_SSE_I387)
16253    && flag_unsafe_math_optimizations && !optimize_size"
16255   rtx op0 = gen_reg_rtx (XFmode);
16257   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16259   ix86_emit_i387_log1p (op0, operands[1]);
16260   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16261   DONE;
16264 (define_insn "*fxtractxf3_i387"
16265   [(set (match_operand:XF 0 "register_operand" "=f")
16266         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16267                    UNSPEC_XTRACT_FRACT))
16268    (set (match_operand:XF 1 "register_operand" "=u")
16269         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16270   "TARGET_USE_FANCY_MATH_387
16271    && flag_unsafe_math_optimizations"
16272   "fxtract"
16273   [(set_attr "type" "fpspc")
16274    (set_attr "mode" "XF")])
16276 (define_insn "fxtract_extend<mode>xf3_i387"
16277   [(set (match_operand:XF 0 "register_operand" "=f")
16278         (unspec:XF [(float_extend:XF
16279                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16280                    UNSPEC_XTRACT_FRACT))
16281    (set (match_operand:XF 1 "register_operand" "=u")
16282         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16283   "TARGET_USE_FANCY_MATH_387
16284    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16285        || TARGET_MIX_SSE_I387)
16286    && flag_unsafe_math_optimizations"
16287   "fxtract"
16288   [(set_attr "type" "fpspc")
16289    (set_attr "mode" "XF")])
16291 (define_expand "logbxf2"
16292   [(parallel [(set (match_dup 2)
16293                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16294                               UNSPEC_XTRACT_FRACT))
16295               (set (match_operand:XF 0 "register_operand" "")
16296                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16297   "TARGET_USE_FANCY_MATH_387
16298    && flag_unsafe_math_optimizations"
16300   operands[2] = gen_reg_rtx (XFmode);
16303 (define_expand "logb<mode>2"
16304   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16305    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16306   "TARGET_USE_FANCY_MATH_387
16307    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16308        || TARGET_MIX_SSE_I387)
16309    && flag_unsafe_math_optimizations"
16311   rtx op0 = gen_reg_rtx (XFmode);
16312   rtx op1 = gen_reg_rtx (XFmode);
16314   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16315   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16316   DONE;
16319 (define_expand "ilogbsi2"
16320   [(parallel [(set (match_dup 2)
16321                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16322                               UNSPEC_XTRACT_FRACT))
16323               (set (match_dup 3)
16324                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16325    (parallel [(set (match_operand:SI 0 "register_operand" "")
16326                    (fix:SI (match_dup 3)))
16327               (clobber (reg:CC FLAGS_REG))])]
16328   "TARGET_USE_FANCY_MATH_387
16329    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16330    && flag_unsafe_math_optimizations && !optimize_size"
16332   operands[2] = gen_reg_rtx (XFmode);
16333   operands[3] = gen_reg_rtx (XFmode);
16336 (define_insn "*f2xm1xf2_i387"
16337   [(set (match_operand:XF 0 "register_operand" "=f")
16338         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16339                    UNSPEC_F2XM1))]
16340   "TARGET_USE_FANCY_MATH_387
16341    && flag_unsafe_math_optimizations"
16342   "f2xm1"
16343   [(set_attr "type" "fpspc")
16344    (set_attr "mode" "XF")])
16346 (define_insn "*fscalexf4_i387"
16347   [(set (match_operand:XF 0 "register_operand" "=f")
16348         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16349                     (match_operand:XF 3 "register_operand" "1")]
16350                    UNSPEC_FSCALE_FRACT))
16351    (set (match_operand:XF 1 "register_operand" "=u")
16352         (unspec:XF [(match_dup 2) (match_dup 3)]
16353                    UNSPEC_FSCALE_EXP))]
16354   "TARGET_USE_FANCY_MATH_387
16355    && flag_unsafe_math_optimizations"
16356   "fscale"
16357   [(set_attr "type" "fpspc")
16358    (set_attr "mode" "XF")])
16360 (define_expand "expNcorexf3"
16361   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16362                                (match_operand:XF 2 "register_operand" "")))
16363    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16364    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16365    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16366    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16367    (parallel [(set (match_operand:XF 0 "register_operand" "")
16368                    (unspec:XF [(match_dup 8) (match_dup 4)]
16369                               UNSPEC_FSCALE_FRACT))
16370               (set (match_dup 9)
16371                    (unspec:XF [(match_dup 8) (match_dup 4)]
16372                               UNSPEC_FSCALE_EXP))])]
16373   "TARGET_USE_FANCY_MATH_387
16374    && flag_unsafe_math_optimizations && !optimize_size"
16376   int i;
16378   for (i = 3; i < 10; i++)
16379     operands[i] = gen_reg_rtx (XFmode);
16381   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16384 (define_expand "expxf2"
16385   [(use (match_operand:XF 0 "register_operand" ""))
16386    (use (match_operand:XF 1 "register_operand" ""))]
16387   "TARGET_USE_FANCY_MATH_387
16388    && flag_unsafe_math_optimizations && !optimize_size"
16390   rtx op2 = gen_reg_rtx (XFmode);
16391   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16393   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16394   DONE;
16397 (define_expand "exp<mode>2"
16398   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16399    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16400  "TARGET_USE_FANCY_MATH_387
16401    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16402        || TARGET_MIX_SSE_I387)
16403    && flag_unsafe_math_optimizations && !optimize_size"
16405   rtx op0 = gen_reg_rtx (XFmode);
16406   rtx op1 = gen_reg_rtx (XFmode);
16408   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16409   emit_insn (gen_expxf2 (op0, op1));
16410   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16411   DONE;
16414 (define_expand "exp10xf2"
16415   [(use (match_operand:XF 0 "register_operand" ""))
16416    (use (match_operand:XF 1 "register_operand" ""))]
16417   "TARGET_USE_FANCY_MATH_387
16418    && flag_unsafe_math_optimizations && !optimize_size"
16420   rtx op2 = gen_reg_rtx (XFmode);
16421   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16423   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16424   DONE;
16427 (define_expand "exp10<mode>2"
16428   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16429    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16430  "TARGET_USE_FANCY_MATH_387
16431    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16432        || TARGET_MIX_SSE_I387)
16433    && flag_unsafe_math_optimizations && !optimize_size"
16435   rtx op0 = gen_reg_rtx (XFmode);
16436   rtx op1 = gen_reg_rtx (XFmode);
16438   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16439   emit_insn (gen_exp10xf2 (op0, op1));
16440   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16441   DONE;
16444 (define_expand "exp2xf2"
16445   [(use (match_operand:XF 0 "register_operand" ""))
16446    (use (match_operand:XF 1 "register_operand" ""))]
16447   "TARGET_USE_FANCY_MATH_387
16448    && flag_unsafe_math_optimizations && !optimize_size"
16450   rtx op2 = gen_reg_rtx (XFmode);
16451   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16453   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16454   DONE;
16457 (define_expand "exp2<mode>2"
16458   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16459    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16460  "TARGET_USE_FANCY_MATH_387
16461    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16462        || TARGET_MIX_SSE_I387)
16463    && flag_unsafe_math_optimizations && !optimize_size"
16465   rtx op0 = gen_reg_rtx (XFmode);
16466   rtx op1 = gen_reg_rtx (XFmode);
16468   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16469   emit_insn (gen_exp2xf2 (op0, op1));
16470   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16471   DONE;
16474 (define_expand "expm1xf2"
16475   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16476                                (match_dup 2)))
16477    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16478    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16479    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16480    (parallel [(set (match_dup 7)
16481                    (unspec:XF [(match_dup 6) (match_dup 4)]
16482                               UNSPEC_FSCALE_FRACT))
16483                    (set (match_dup 8)
16484                    (unspec:XF [(match_dup 6) (match_dup 4)]
16485                               UNSPEC_FSCALE_EXP))])
16486    (parallel [(set (match_dup 10)
16487                    (unspec:XF [(match_dup 9) (match_dup 8)]
16488                               UNSPEC_FSCALE_FRACT))
16489               (set (match_dup 11)
16490                    (unspec:XF [(match_dup 9) (match_dup 8)]
16491                               UNSPEC_FSCALE_EXP))])
16492    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16493    (set (match_operand:XF 0 "register_operand" "")
16494         (plus:XF (match_dup 12) (match_dup 7)))]
16495   "TARGET_USE_FANCY_MATH_387
16496    && flag_unsafe_math_optimizations && !optimize_size"
16498   int i;
16500   for (i = 2; i < 13; i++)
16501     operands[i] = gen_reg_rtx (XFmode);
16503   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16504   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16507 (define_expand "expm1<mode>2"
16508   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16509    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16510  "TARGET_USE_FANCY_MATH_387
16511    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16512        || TARGET_MIX_SSE_I387)
16513    && flag_unsafe_math_optimizations && !optimize_size"
16515   rtx op0 = gen_reg_rtx (XFmode);
16516   rtx op1 = gen_reg_rtx (XFmode);
16518   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16519   emit_insn (gen_expm1xf2 (op0, op1));
16520   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16521   DONE;
16524 (define_expand "ldexpxf3"
16525   [(set (match_dup 3)
16526         (float:XF (match_operand:SI 2 "register_operand" "")))
16527    (parallel [(set (match_operand:XF 0 " register_operand" "")
16528                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16529                                (match_dup 3)]
16530                               UNSPEC_FSCALE_FRACT))
16531               (set (match_dup 4)
16532                    (unspec:XF [(match_dup 1) (match_dup 3)]
16533                               UNSPEC_FSCALE_EXP))])]
16534   "TARGET_USE_FANCY_MATH_387
16535    && flag_unsafe_math_optimizations && !optimize_size"
16537   operands[3] = gen_reg_rtx (XFmode);
16538   operands[4] = gen_reg_rtx (XFmode);
16541 (define_expand "ldexp<mode>3"
16542   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16543    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16544    (use (match_operand:SI 2 "register_operand" ""))]
16545  "TARGET_USE_FANCY_MATH_387
16546    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16547        || TARGET_MIX_SSE_I387)
16548    && flag_unsafe_math_optimizations && !optimize_size"
16550   rtx op0 = gen_reg_rtx (XFmode);
16551   rtx op1 = gen_reg_rtx (XFmode);
16553   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16554   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16555   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16556   DONE;
16560 (define_insn "frndintxf2"
16561   [(set (match_operand:XF 0 "register_operand" "=f")
16562         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16563          UNSPEC_FRNDINT))]
16564   "TARGET_USE_FANCY_MATH_387
16565    && flag_unsafe_math_optimizations"
16566   "frndint"
16567   [(set_attr "type" "fpspc")
16568    (set_attr "mode" "XF")])
16570 (define_expand "rintdf2"
16571   [(use (match_operand:DF 0 "register_operand" ""))
16572    (use (match_operand:DF 1 "register_operand" ""))]
16573   "(TARGET_USE_FANCY_MATH_387
16574     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16575     && flag_unsafe_math_optimizations)
16576    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16577        && !flag_trapping_math
16578        && !optimize_size)"
16580   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16581       && !flag_trapping_math
16582       && !optimize_size)
16583     ix86_expand_rint (operand0, operand1);
16584   else
16585     {
16586       rtx op0 = gen_reg_rtx (XFmode);
16587       rtx op1 = gen_reg_rtx (XFmode);
16589       emit_insn (gen_extenddfxf2 (op1, operands[1]));
16590       emit_insn (gen_frndintxf2 (op0, op1));
16592       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16593     }
16594   DONE;
16597 (define_expand "rintsf2"
16598   [(use (match_operand:SF 0 "register_operand" ""))
16599    (use (match_operand:SF 1 "register_operand" ""))]
16600   "(TARGET_USE_FANCY_MATH_387
16601     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16602     && flag_unsafe_math_optimizations)
16603    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16604        && !flag_trapping_math
16605        && !optimize_size)"
16607   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16608       && !flag_trapping_math
16609       && !optimize_size)
16610     ix86_expand_rint (operand0, operand1);
16611   else
16612     {
16613       rtx op0 = gen_reg_rtx (XFmode);
16614       rtx op1 = gen_reg_rtx (XFmode);
16616       emit_insn (gen_extendsfxf2 (op1, operands[1]));
16617       emit_insn (gen_frndintxf2 (op0, op1));
16619       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16620     }
16621   DONE;
16624 (define_expand "rintxf2"
16625   [(use (match_operand:XF 0 "register_operand" ""))
16626    (use (match_operand:XF 1 "register_operand" ""))]
16627   "TARGET_USE_FANCY_MATH_387
16628    && flag_unsafe_math_optimizations && !optimize_size"
16630   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16631   DONE;
16634 (define_expand "roundsf2"
16635   [(match_operand:SF 0 "register_operand" "")
16636    (match_operand:SF 1 "nonimmediate_operand" "")]
16637   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16638    && !flag_trapping_math && !flag_rounding_math
16639    && !optimize_size"
16641   ix86_expand_round (operand0, operand1);
16642   DONE;
16645 (define_expand "rounddf2"
16646   [(match_operand:DF 0 "register_operand" "")
16647    (match_operand:DF 1 "nonimmediate_operand" "")]
16648   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16649    && !flag_trapping_math && !flag_rounding_math
16650    && !optimize_size"
16652   if (TARGET_64BIT)
16653     ix86_expand_round (operand0, operand1);
16654   else
16655     ix86_expand_rounddf_32 (operand0, operand1);
16656   DONE;
16659 (define_insn_and_split "*fistdi2_1"
16660   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16661         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16662          UNSPEC_FIST))]
16663   "TARGET_USE_FANCY_MATH_387
16664    && !(reload_completed || reload_in_progress)"
16665   "#"
16666   "&& 1"
16667   [(const_int 0)]
16669   if (memory_operand (operands[0], VOIDmode))
16670     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16671   else
16672     {
16673       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16674       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16675                                          operands[2]));
16676     }
16677   DONE;
16679   [(set_attr "type" "fpspc")
16680    (set_attr "mode" "DI")])
16682 (define_insn "fistdi2"
16683   [(set (match_operand:DI 0 "memory_operand" "=m")
16684         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16685          UNSPEC_FIST))
16686    (clobber (match_scratch:XF 2 "=&1f"))]
16687   "TARGET_USE_FANCY_MATH_387"
16688   "* return output_fix_trunc (insn, operands, 0);"
16689   [(set_attr "type" "fpspc")
16690    (set_attr "mode" "DI")])
16692 (define_insn "fistdi2_with_temp"
16693   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16694         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16695          UNSPEC_FIST))
16696    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16697    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16698   "TARGET_USE_FANCY_MATH_387"
16699   "#"
16700   [(set_attr "type" "fpspc")
16701    (set_attr "mode" "DI")])
16703 (define_split
16704   [(set (match_operand:DI 0 "register_operand" "")
16705         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16706          UNSPEC_FIST))
16707    (clobber (match_operand:DI 2 "memory_operand" ""))
16708    (clobber (match_scratch 3 ""))]
16709   "reload_completed"
16710   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16711               (clobber (match_dup 3))])
16712    (set (match_dup 0) (match_dup 2))]
16713   "")
16715 (define_split
16716   [(set (match_operand:DI 0 "memory_operand" "")
16717         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16718          UNSPEC_FIST))
16719    (clobber (match_operand:DI 2 "memory_operand" ""))
16720    (clobber (match_scratch 3 ""))]
16721   "reload_completed"
16722   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16723               (clobber (match_dup 3))])]
16724   "")
16726 (define_insn_and_split "*fist<mode>2_1"
16727   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16728         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16729          UNSPEC_FIST))]
16730   "TARGET_USE_FANCY_MATH_387
16731    && !(reload_completed || reload_in_progress)"
16732   "#"
16733   "&& 1"
16734   [(const_int 0)]
16736   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16737   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16738                                         operands[2]));
16739   DONE;
16741   [(set_attr "type" "fpspc")
16742    (set_attr "mode" "<MODE>")])
16744 (define_insn "fist<mode>2"
16745   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16746         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16747          UNSPEC_FIST))]
16748   "TARGET_USE_FANCY_MATH_387"
16749   "* return output_fix_trunc (insn, operands, 0);"
16750   [(set_attr "type" "fpspc")
16751    (set_attr "mode" "<MODE>")])
16753 (define_insn "fist<mode>2_with_temp"
16754   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16755         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16756          UNSPEC_FIST))
16757    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16758   "TARGET_USE_FANCY_MATH_387"
16759   "#"
16760   [(set_attr "type" "fpspc")
16761    (set_attr "mode" "<MODE>")])
16763 (define_split
16764   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16765         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16766          UNSPEC_FIST))
16767    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16768   "reload_completed"
16769   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16770                        UNSPEC_FIST))
16771    (set (match_dup 0) (match_dup 2))]
16772   "")
16774 (define_split
16775   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16776         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16777          UNSPEC_FIST))
16778    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16779   "reload_completed"
16780   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16781                        UNSPEC_FIST))]
16782   "")
16784 (define_expand "lrintxf<mode>2"
16785   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16786      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16787       UNSPEC_FIST))]
16788   "TARGET_USE_FANCY_MATH_387"
16789   "")
16791 (define_expand "lrint<mode>di2"
16792   [(set (match_operand:DI 0 "nonimmediate_operand" "")
16793      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
16794       UNSPEC_FIX_NOTRUNC))]
16795   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
16796   "")
16798 (define_expand "lrint<mode>si2"
16799   [(set (match_operand:SI 0 "nonimmediate_operand" "")
16800      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
16801       UNSPEC_FIX_NOTRUNC))]
16802   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16803   "")
16805 (define_expand "lround<mode>di2"
16806   [(match_operand:DI 0 "nonimmediate_operand" "")
16807    (match_operand:SSEMODEF 1 "register_operand" "")]
16808   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
16809    && !flag_trapping_math && !flag_rounding_math
16810    && !optimize_size"
16812   ix86_expand_lround (operand0, operand1);
16813   DONE;
16816 (define_expand "lround<mode>si2"
16817   [(match_operand:SI 0 "nonimmediate_operand" "")
16818    (match_operand:SSEMODEF 1 "register_operand" "")]
16819   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16820    && !flag_trapping_math && !flag_rounding_math
16821    && !optimize_size"
16823   ix86_expand_lround (operand0, operand1);
16824   DONE;
16827 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16828 (define_insn_and_split "frndintxf2_floor"
16829   [(set (match_operand:XF 0 "register_operand" "=f")
16830         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16831          UNSPEC_FRNDINT_FLOOR))
16832    (clobber (reg:CC FLAGS_REG))]
16833   "TARGET_USE_FANCY_MATH_387
16834    && flag_unsafe_math_optimizations
16835    && !(reload_completed || reload_in_progress)"
16836   "#"
16837   "&& 1"
16838   [(const_int 0)]
16840   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16842   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16843   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16845   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16846                                         operands[2], operands[3]));
16847   DONE;
16849   [(set_attr "type" "frndint")
16850    (set_attr "i387_cw" "floor")
16851    (set_attr "mode" "XF")])
16853 (define_insn "frndintxf2_floor_i387"
16854   [(set (match_operand:XF 0 "register_operand" "=f")
16855         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16856          UNSPEC_FRNDINT_FLOOR))
16857    (use (match_operand:HI 2 "memory_operand" "m"))
16858    (use (match_operand:HI 3 "memory_operand" "m"))]
16859   "TARGET_USE_FANCY_MATH_387
16860    && flag_unsafe_math_optimizations"
16861   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16862   [(set_attr "type" "frndint")
16863    (set_attr "i387_cw" "floor")
16864    (set_attr "mode" "XF")])
16866 (define_expand "floorxf2"
16867   [(use (match_operand:XF 0 "register_operand" ""))
16868    (use (match_operand:XF 1 "register_operand" ""))]
16869   "TARGET_USE_FANCY_MATH_387
16870    && flag_unsafe_math_optimizations && !optimize_size"
16872   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16873   DONE;
16876 (define_expand "floordf2"
16877   [(use (match_operand:DF 0 "register_operand" ""))
16878    (use (match_operand:DF 1 "register_operand" ""))]
16879   "((TARGET_USE_FANCY_MATH_387
16880      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16881      && flag_unsafe_math_optimizations)
16882     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16883         && !flag_trapping_math))
16884    && !optimize_size"
16886   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16887       && !flag_trapping_math)
16888     {
16889       if (TARGET_64BIT)
16890         ix86_expand_floorceil (operand0, operand1, true);
16891       else
16892         ix86_expand_floorceildf_32 (operand0, operand1, true);
16893     }
16894   else
16895     {
16896       rtx op0 = gen_reg_rtx (XFmode);
16897       rtx op1 = gen_reg_rtx (XFmode);
16899       emit_insn (gen_extenddfxf2 (op1, operands[1]));
16900       emit_insn (gen_frndintxf2_floor (op0, op1));
16902       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16903     }
16904   DONE;
16907 (define_expand "floorsf2"
16908   [(use (match_operand:SF 0 "register_operand" ""))
16909    (use (match_operand:SF 1 "register_operand" ""))]
16910   "((TARGET_USE_FANCY_MATH_387
16911      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16912      && flag_unsafe_math_optimizations)
16913     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16914         && !flag_trapping_math))
16915    && !optimize_size"
16917   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16918       && !flag_trapping_math)
16919     ix86_expand_floorceil (operand0, operand1, true);
16920   else
16921     {
16922       rtx op0 = gen_reg_rtx (XFmode);
16923       rtx op1 = gen_reg_rtx (XFmode);
16925       emit_insn (gen_extendsfxf2 (op1, operands[1]));
16926       emit_insn (gen_frndintxf2_floor (op0, op1));
16928       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16929     }
16930   DONE;
16933 (define_insn_and_split "*fist<mode>2_floor_1"
16934   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16935         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16936          UNSPEC_FIST_FLOOR))
16937    (clobber (reg:CC FLAGS_REG))]
16938   "TARGET_USE_FANCY_MATH_387
16939    && flag_unsafe_math_optimizations
16940    && !(reload_completed || reload_in_progress)"
16941   "#"
16942   "&& 1"
16943   [(const_int 0)]
16945   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16947   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16948   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16949   if (memory_operand (operands[0], VOIDmode))
16950     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16951                                       operands[2], operands[3]));
16952   else
16953     {
16954       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16955       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16956                                                   operands[2], operands[3],
16957                                                   operands[4]));
16958     }
16959   DONE;
16961   [(set_attr "type" "fistp")
16962    (set_attr "i387_cw" "floor")
16963    (set_attr "mode" "<MODE>")])
16965 (define_insn "fistdi2_floor"
16966   [(set (match_operand:DI 0 "memory_operand" "=m")
16967         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16968          UNSPEC_FIST_FLOOR))
16969    (use (match_operand:HI 2 "memory_operand" "m"))
16970    (use (match_operand:HI 3 "memory_operand" "m"))
16971    (clobber (match_scratch:XF 4 "=&1f"))]
16972   "TARGET_USE_FANCY_MATH_387
16973    && flag_unsafe_math_optimizations"
16974   "* return output_fix_trunc (insn, operands, 0);"
16975   [(set_attr "type" "fistp")
16976    (set_attr "i387_cw" "floor")
16977    (set_attr "mode" "DI")])
16979 (define_insn "fistdi2_floor_with_temp"
16980   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16981         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16982          UNSPEC_FIST_FLOOR))
16983    (use (match_operand:HI 2 "memory_operand" "m,m"))
16984    (use (match_operand:HI 3 "memory_operand" "m,m"))
16985    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16986    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16987   "TARGET_USE_FANCY_MATH_387
16988    && flag_unsafe_math_optimizations"
16989   "#"
16990   [(set_attr "type" "fistp")
16991    (set_attr "i387_cw" "floor")
16992    (set_attr "mode" "DI")])
16994 (define_split
16995   [(set (match_operand:DI 0 "register_operand" "")
16996         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16997          UNSPEC_FIST_FLOOR))
16998    (use (match_operand:HI 2 "memory_operand" ""))
16999    (use (match_operand:HI 3 "memory_operand" ""))
17000    (clobber (match_operand:DI 4 "memory_operand" ""))
17001    (clobber (match_scratch 5 ""))]
17002   "reload_completed"
17003   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17004               (use (match_dup 2))
17005               (use (match_dup 3))
17006               (clobber (match_dup 5))])
17007    (set (match_dup 0) (match_dup 4))]
17008   "")
17010 (define_split
17011   [(set (match_operand:DI 0 "memory_operand" "")
17012         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17013          UNSPEC_FIST_FLOOR))
17014    (use (match_operand:HI 2 "memory_operand" ""))
17015    (use (match_operand:HI 3 "memory_operand" ""))
17016    (clobber (match_operand:DI 4 "memory_operand" ""))
17017    (clobber (match_scratch 5 ""))]
17018   "reload_completed"
17019   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17020               (use (match_dup 2))
17021               (use (match_dup 3))
17022               (clobber (match_dup 5))])]
17023   "")
17025 (define_insn "fist<mode>2_floor"
17026   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17027         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17028          UNSPEC_FIST_FLOOR))
17029    (use (match_operand:HI 2 "memory_operand" "m"))
17030    (use (match_operand:HI 3 "memory_operand" "m"))]
17031   "TARGET_USE_FANCY_MATH_387
17032    && flag_unsafe_math_optimizations"
17033   "* return output_fix_trunc (insn, operands, 0);"
17034   [(set_attr "type" "fistp")
17035    (set_attr "i387_cw" "floor")
17036    (set_attr "mode" "<MODE>")])
17038 (define_insn "fist<mode>2_floor_with_temp"
17039   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17040         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17041          UNSPEC_FIST_FLOOR))
17042    (use (match_operand:HI 2 "memory_operand" "m,m"))
17043    (use (match_operand:HI 3 "memory_operand" "m,m"))
17044    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17045   "TARGET_USE_FANCY_MATH_387
17046    && flag_unsafe_math_optimizations"
17047   "#"
17048   [(set_attr "type" "fistp")
17049    (set_attr "i387_cw" "floor")
17050    (set_attr "mode" "<MODE>")])
17052 (define_split
17053   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17054         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17055          UNSPEC_FIST_FLOOR))
17056    (use (match_operand:HI 2 "memory_operand" ""))
17057    (use (match_operand:HI 3 "memory_operand" ""))
17058    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17059   "reload_completed"
17060   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17061                                   UNSPEC_FIST_FLOOR))
17062               (use (match_dup 2))
17063               (use (match_dup 3))])
17064    (set (match_dup 0) (match_dup 4))]
17065   "")
17067 (define_split
17068   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17069         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17070          UNSPEC_FIST_FLOOR))
17071    (use (match_operand:HI 2 "memory_operand" ""))
17072    (use (match_operand:HI 3 "memory_operand" ""))
17073    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17074   "reload_completed"
17075   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17076                                   UNSPEC_FIST_FLOOR))
17077               (use (match_dup 2))
17078               (use (match_dup 3))])]
17079   "")
17081 (define_expand "lfloorxf<mode>2"
17082   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17083                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17084                     UNSPEC_FIST_FLOOR))
17085               (clobber (reg:CC FLAGS_REG))])]
17086   "TARGET_USE_FANCY_MATH_387
17087    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17088    && flag_unsafe_math_optimizations"
17089   "")
17091 (define_expand "lfloor<mode>di2"
17092   [(match_operand:DI 0 "nonimmediate_operand" "")
17093    (match_operand:SSEMODEF 1 "register_operand" "")]
17094   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17095    && !flag_trapping_math
17096    && !optimize_size"
17098   ix86_expand_lfloorceil (operand0, operand1, true);
17099   DONE;
17102 (define_expand "lfloor<mode>si2"
17103   [(match_operand:SI 0 "nonimmediate_operand" "")
17104    (match_operand:SSEMODEF 1 "register_operand" "")]
17105   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17106    && !flag_trapping_math
17107    && (!optimize_size || !TARGET_64BIT)"
17109   ix86_expand_lfloorceil (operand0, operand1, true);
17110   DONE;
17113 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17114 (define_insn_and_split "frndintxf2_ceil"
17115   [(set (match_operand:XF 0 "register_operand" "=f")
17116         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17117          UNSPEC_FRNDINT_CEIL))
17118    (clobber (reg:CC FLAGS_REG))]
17119   "TARGET_USE_FANCY_MATH_387
17120    && flag_unsafe_math_optimizations
17121    && !(reload_completed || reload_in_progress)"
17122   "#"
17123   "&& 1"
17124   [(const_int 0)]
17126   ix86_optimize_mode_switching[I387_CEIL] = 1;
17128   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17129   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17131   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17132                                        operands[2], operands[3]));
17133   DONE;
17135   [(set_attr "type" "frndint")
17136    (set_attr "i387_cw" "ceil")
17137    (set_attr "mode" "XF")])
17139 (define_insn "frndintxf2_ceil_i387"
17140   [(set (match_operand:XF 0 "register_operand" "=f")
17141         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17142          UNSPEC_FRNDINT_CEIL))
17143    (use (match_operand:HI 2 "memory_operand" "m"))
17144    (use (match_operand:HI 3 "memory_operand" "m"))]
17145   "TARGET_USE_FANCY_MATH_387
17146    && flag_unsafe_math_optimizations"
17147   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17148   [(set_attr "type" "frndint")
17149    (set_attr "i387_cw" "ceil")
17150    (set_attr "mode" "XF")])
17152 (define_expand "ceilxf2"
17153   [(use (match_operand:XF 0 "register_operand" ""))
17154    (use (match_operand:XF 1 "register_operand" ""))]
17155   "TARGET_USE_FANCY_MATH_387
17156    && flag_unsafe_math_optimizations && !optimize_size"
17158   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17159   DONE;
17162 (define_expand "ceildf2"
17163   [(use (match_operand:DF 0 "register_operand" ""))
17164    (use (match_operand:DF 1 "register_operand" ""))]
17165   "((TARGET_USE_FANCY_MATH_387
17166      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17167      && flag_unsafe_math_optimizations)
17168     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17169         && !flag_trapping_math))
17170    && !optimize_size"
17172   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17173       && !flag_trapping_math)
17174     {
17175       if (TARGET_64BIT)
17176         ix86_expand_floorceil (operand0, operand1, false);
17177       else
17178         ix86_expand_floorceildf_32 (operand0, operand1, false);
17179     }
17180   else
17181     {
17182       rtx op0 = gen_reg_rtx (XFmode);
17183       rtx op1 = gen_reg_rtx (XFmode);
17185       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17186       emit_insn (gen_frndintxf2_ceil (op0, op1));
17188       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17189     }
17190   DONE;
17193 (define_expand "ceilsf2"
17194   [(use (match_operand:SF 0 "register_operand" ""))
17195    (use (match_operand:SF 1 "register_operand" ""))]
17196   "((TARGET_USE_FANCY_MATH_387
17197      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17198      && flag_unsafe_math_optimizations)
17199     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17200         && !flag_trapping_math))
17201    && !optimize_size"
17203   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17204       && !flag_trapping_math)
17205     ix86_expand_floorceil (operand0, operand1, false);
17206   else
17207     {
17208       rtx op0 = gen_reg_rtx (XFmode);
17209       rtx op1 = gen_reg_rtx (XFmode);
17211       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17212       emit_insn (gen_frndintxf2_ceil (op0, op1));
17214       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17215     }
17216   DONE;
17219 (define_insn_and_split "*fist<mode>2_ceil_1"
17220   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17221         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17222          UNSPEC_FIST_CEIL))
17223    (clobber (reg:CC FLAGS_REG))]
17224   "TARGET_USE_FANCY_MATH_387
17225    && flag_unsafe_math_optimizations
17226    && !(reload_completed || reload_in_progress)"
17227   "#"
17228   "&& 1"
17229   [(const_int 0)]
17231   ix86_optimize_mode_switching[I387_CEIL] = 1;
17233   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17234   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17235   if (memory_operand (operands[0], VOIDmode))
17236     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17237                                      operands[2], operands[3]));
17238   else
17239     {
17240       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17241       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17242                                                  operands[2], operands[3],
17243                                                  operands[4]));
17244     }
17245   DONE;
17247   [(set_attr "type" "fistp")
17248    (set_attr "i387_cw" "ceil")
17249    (set_attr "mode" "<MODE>")])
17251 (define_insn "fistdi2_ceil"
17252   [(set (match_operand:DI 0 "memory_operand" "=m")
17253         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17254          UNSPEC_FIST_CEIL))
17255    (use (match_operand:HI 2 "memory_operand" "m"))
17256    (use (match_operand:HI 3 "memory_operand" "m"))
17257    (clobber (match_scratch:XF 4 "=&1f"))]
17258   "TARGET_USE_FANCY_MATH_387
17259    && flag_unsafe_math_optimizations"
17260   "* return output_fix_trunc (insn, operands, 0);"
17261   [(set_attr "type" "fistp")
17262    (set_attr "i387_cw" "ceil")
17263    (set_attr "mode" "DI")])
17265 (define_insn "fistdi2_ceil_with_temp"
17266   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17267         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17268          UNSPEC_FIST_CEIL))
17269    (use (match_operand:HI 2 "memory_operand" "m,m"))
17270    (use (match_operand:HI 3 "memory_operand" "m,m"))
17271    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17272    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17273   "TARGET_USE_FANCY_MATH_387
17274    && flag_unsafe_math_optimizations"
17275   "#"
17276   [(set_attr "type" "fistp")
17277    (set_attr "i387_cw" "ceil")
17278    (set_attr "mode" "DI")])
17280 (define_split
17281   [(set (match_operand:DI 0 "register_operand" "")
17282         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17283          UNSPEC_FIST_CEIL))
17284    (use (match_operand:HI 2 "memory_operand" ""))
17285    (use (match_operand:HI 3 "memory_operand" ""))
17286    (clobber (match_operand:DI 4 "memory_operand" ""))
17287    (clobber (match_scratch 5 ""))]
17288   "reload_completed"
17289   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17290               (use (match_dup 2))
17291               (use (match_dup 3))
17292               (clobber (match_dup 5))])
17293    (set (match_dup 0) (match_dup 4))]
17294   "")
17296 (define_split
17297   [(set (match_operand:DI 0 "memory_operand" "")
17298         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17299          UNSPEC_FIST_CEIL))
17300    (use (match_operand:HI 2 "memory_operand" ""))
17301    (use (match_operand:HI 3 "memory_operand" ""))
17302    (clobber (match_operand:DI 4 "memory_operand" ""))
17303    (clobber (match_scratch 5 ""))]
17304   "reload_completed"
17305   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17306               (use (match_dup 2))
17307               (use (match_dup 3))
17308               (clobber (match_dup 5))])]
17309   "")
17311 (define_insn "fist<mode>2_ceil"
17312   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17313         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17314          UNSPEC_FIST_CEIL))
17315    (use (match_operand:HI 2 "memory_operand" "m"))
17316    (use (match_operand:HI 3 "memory_operand" "m"))]
17317   "TARGET_USE_FANCY_MATH_387
17318    && flag_unsafe_math_optimizations"
17319   "* return output_fix_trunc (insn, operands, 0);"
17320   [(set_attr "type" "fistp")
17321    (set_attr "i387_cw" "ceil")
17322    (set_attr "mode" "<MODE>")])
17324 (define_insn "fist<mode>2_ceil_with_temp"
17325   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17326         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17327          UNSPEC_FIST_CEIL))
17328    (use (match_operand:HI 2 "memory_operand" "m,m"))
17329    (use (match_operand:HI 3 "memory_operand" "m,m"))
17330    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17331   "TARGET_USE_FANCY_MATH_387
17332    && flag_unsafe_math_optimizations"
17333   "#"
17334   [(set_attr "type" "fistp")
17335    (set_attr "i387_cw" "ceil")
17336    (set_attr "mode" "<MODE>")])
17338 (define_split
17339   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17340         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17341          UNSPEC_FIST_CEIL))
17342    (use (match_operand:HI 2 "memory_operand" ""))
17343    (use (match_operand:HI 3 "memory_operand" ""))
17344    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17345   "reload_completed"
17346   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17347                                   UNSPEC_FIST_CEIL))
17348               (use (match_dup 2))
17349               (use (match_dup 3))])
17350    (set (match_dup 0) (match_dup 4))]
17351   "")
17353 (define_split
17354   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17355         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17356          UNSPEC_FIST_CEIL))
17357    (use (match_operand:HI 2 "memory_operand" ""))
17358    (use (match_operand:HI 3 "memory_operand" ""))
17359    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17360   "reload_completed"
17361   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17362                                   UNSPEC_FIST_CEIL))
17363               (use (match_dup 2))
17364               (use (match_dup 3))])]
17365   "")
17367 (define_expand "lceilxf<mode>2"
17368   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17369                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17370                     UNSPEC_FIST_CEIL))
17371               (clobber (reg:CC FLAGS_REG))])]
17372   "TARGET_USE_FANCY_MATH_387
17373    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17374    && flag_unsafe_math_optimizations"
17375   "")
17377 (define_expand "lceil<mode>di2"
17378   [(match_operand:DI 0 "nonimmediate_operand" "")
17379    (match_operand:SSEMODEF 1 "register_operand" "")]
17380   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17381    && !flag_trapping_math"
17383   ix86_expand_lfloorceil (operand0, operand1, false);
17384   DONE;
17387 (define_expand "lceil<mode>si2"
17388   [(match_operand:SI 0 "nonimmediate_operand" "")
17389    (match_operand:SSEMODEF 1 "register_operand" "")]
17390   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17391    && !flag_trapping_math"
17393   ix86_expand_lfloorceil (operand0, operand1, false);
17394   DONE;
17397 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17398 (define_insn_and_split "frndintxf2_trunc"
17399   [(set (match_operand:XF 0 "register_operand" "=f")
17400         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17401          UNSPEC_FRNDINT_TRUNC))
17402    (clobber (reg:CC FLAGS_REG))]
17403   "TARGET_USE_FANCY_MATH_387
17404    && flag_unsafe_math_optimizations
17405    && !(reload_completed || reload_in_progress)"
17406   "#"
17407   "&& 1"
17408   [(const_int 0)]
17410   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17412   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17413   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17415   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17416                                         operands[2], operands[3]));
17417   DONE;
17419   [(set_attr "type" "frndint")
17420    (set_attr "i387_cw" "trunc")
17421    (set_attr "mode" "XF")])
17423 (define_insn "frndintxf2_trunc_i387"
17424   [(set (match_operand:XF 0 "register_operand" "=f")
17425         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17426          UNSPEC_FRNDINT_TRUNC))
17427    (use (match_operand:HI 2 "memory_operand" "m"))
17428    (use (match_operand:HI 3 "memory_operand" "m"))]
17429   "TARGET_USE_FANCY_MATH_387
17430    && flag_unsafe_math_optimizations"
17431   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17432   [(set_attr "type" "frndint")
17433    (set_attr "i387_cw" "trunc")
17434    (set_attr "mode" "XF")])
17436 (define_expand "btruncxf2"
17437   [(use (match_operand:XF 0 "register_operand" ""))
17438    (use (match_operand:XF 1 "register_operand" ""))]
17439   "TARGET_USE_FANCY_MATH_387
17440    && flag_unsafe_math_optimizations && !optimize_size"
17442   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17443   DONE;
17446 (define_expand "btruncdf2"
17447   [(use (match_operand:DF 0 "register_operand" ""))
17448    (use (match_operand:DF 1 "register_operand" ""))]
17449   "((TARGET_USE_FANCY_MATH_387
17450      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17451      && flag_unsafe_math_optimizations)
17452     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17453         && !flag_trapping_math))
17454    && !optimize_size"
17456   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17457       && !flag_trapping_math)
17458     {
17459       if (TARGET_64BIT)
17460         ix86_expand_trunc (operand0, operand1);
17461       else
17462         ix86_expand_truncdf_32 (operand0, operand1);
17463     }
17464   else
17465     {
17466       rtx op0 = gen_reg_rtx (XFmode);
17467       rtx op1 = gen_reg_rtx (XFmode);
17469       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17470       emit_insn (gen_frndintxf2_trunc (op0, op1));
17472       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17473     }
17474   DONE;
17477 (define_expand "btruncsf2"
17478   [(use (match_operand:SF 0 "register_operand" ""))
17479    (use (match_operand:SF 1 "register_operand" ""))]
17480   "((TARGET_USE_FANCY_MATH_387
17481      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17482      && flag_unsafe_math_optimizations)
17483     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17484         && !flag_trapping_math))
17485    && !optimize_size"
17487   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17488       && !flag_trapping_math)
17489     ix86_expand_trunc (operand0, operand1);
17490   else
17491     {
17492       rtx op0 = gen_reg_rtx (XFmode);
17493       rtx op1 = gen_reg_rtx (XFmode);
17495       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17496       emit_insn (gen_frndintxf2_trunc (op0, op1));
17498       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17499     }
17500   DONE;
17503 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17504 (define_insn_and_split "frndintxf2_mask_pm"
17505   [(set (match_operand:XF 0 "register_operand" "=f")
17506         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17507          UNSPEC_FRNDINT_MASK_PM))
17508    (clobber (reg:CC FLAGS_REG))]
17509   "TARGET_USE_FANCY_MATH_387
17510    && flag_unsafe_math_optimizations
17511    && !(reload_completed || reload_in_progress)"
17512   "#"
17513   "&& 1"
17514   [(const_int 0)]
17516   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17518   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17519   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17521   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17522                                           operands[2], operands[3]));
17523   DONE;
17525   [(set_attr "type" "frndint")
17526    (set_attr "i387_cw" "mask_pm")
17527    (set_attr "mode" "XF")])
17529 (define_insn "frndintxf2_mask_pm_i387"
17530   [(set (match_operand:XF 0 "register_operand" "=f")
17531         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17532          UNSPEC_FRNDINT_MASK_PM))
17533    (use (match_operand:HI 2 "memory_operand" "m"))
17534    (use (match_operand:HI 3 "memory_operand" "m"))]
17535   "TARGET_USE_FANCY_MATH_387
17536    && flag_unsafe_math_optimizations"
17537   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17538   [(set_attr "type" "frndint")
17539    (set_attr "i387_cw" "mask_pm")
17540    (set_attr "mode" "XF")])
17542 (define_expand "nearbyintxf2"
17543   [(use (match_operand:XF 0 "register_operand" ""))
17544    (use (match_operand:XF 1 "register_operand" ""))]
17545   "TARGET_USE_FANCY_MATH_387
17546    && flag_unsafe_math_optimizations"
17548   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17550   DONE;
17553 (define_expand "nearbyintdf2"
17554   [(use (match_operand:DF 0 "register_operand" ""))
17555    (use (match_operand:DF 1 "register_operand" ""))]
17556   "TARGET_USE_FANCY_MATH_387
17557    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17558    && flag_unsafe_math_optimizations"
17560   rtx op0 = gen_reg_rtx (XFmode);
17561   rtx op1 = gen_reg_rtx (XFmode);
17563   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17564   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17566   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17567   DONE;
17570 (define_expand "nearbyintsf2"
17571   [(use (match_operand:SF 0 "register_operand" ""))
17572    (use (match_operand:SF 1 "register_operand" ""))]
17573   "TARGET_USE_FANCY_MATH_387
17574    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17575    && flag_unsafe_math_optimizations"
17577   rtx op0 = gen_reg_rtx (XFmode);
17578   rtx op1 = gen_reg_rtx (XFmode);
17580   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17581   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17583   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17584   DONE;
17588 ;; Block operation instructions
17590 (define_expand "movmemsi"
17591   [(use (match_operand:BLK 0 "memory_operand" ""))
17592    (use (match_operand:BLK 1 "memory_operand" ""))
17593    (use (match_operand:SI 2 "nonmemory_operand" ""))
17594    (use (match_operand:SI 3 "const_int_operand" ""))
17595    (use (match_operand:SI 4 "const_int_operand" ""))
17596    (use (match_operand:SI 5 "const_int_operand" ""))]
17597   ""
17599  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17600                          operands[4], operands[5]))
17601    DONE;
17602  else
17603    FAIL;
17606 (define_expand "movmemdi"
17607   [(use (match_operand:BLK 0 "memory_operand" ""))
17608    (use (match_operand:BLK 1 "memory_operand" ""))
17609    (use (match_operand:DI 2 "nonmemory_operand" ""))
17610    (use (match_operand:DI 3 "const_int_operand" ""))
17611    (use (match_operand:SI 4 "const_int_operand" ""))
17612    (use (match_operand:SI 5 "const_int_operand" ""))]
17613   "TARGET_64BIT"
17615  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17616                          operands[4], operands[5]))
17617    DONE;
17618  else
17619    FAIL;
17622 ;; Most CPUs don't like single string operations
17623 ;; Handle this case here to simplify previous expander.
17625 (define_expand "strmov"
17626   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17627    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17628    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17629               (clobber (reg:CC FLAGS_REG))])
17630    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17631               (clobber (reg:CC FLAGS_REG))])]
17632   ""
17634   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17636   /* If .md ever supports :P for Pmode, these can be directly
17637      in the pattern above.  */
17638   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17639   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17641   if (TARGET_SINGLE_STRINGOP || optimize_size)
17642     {
17643       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17644                                       operands[2], operands[3],
17645                                       operands[5], operands[6]));
17646       DONE;
17647     }
17649   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17652 (define_expand "strmov_singleop"
17653   [(parallel [(set (match_operand 1 "memory_operand" "")
17654                    (match_operand 3 "memory_operand" ""))
17655               (set (match_operand 0 "register_operand" "")
17656                    (match_operand 4 "" ""))
17657               (set (match_operand 2 "register_operand" "")
17658                    (match_operand 5 "" ""))])]
17659   "TARGET_SINGLE_STRINGOP || optimize_size"
17660   "")
17662 (define_insn "*strmovdi_rex_1"
17663   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17664         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17665    (set (match_operand:DI 0 "register_operand" "=D")
17666         (plus:DI (match_dup 2)
17667                  (const_int 8)))
17668    (set (match_operand:DI 1 "register_operand" "=S")
17669         (plus:DI (match_dup 3)
17670                  (const_int 8)))]
17671   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17672   "movsq"
17673   [(set_attr "type" "str")
17674    (set_attr "mode" "DI")
17675    (set_attr "memory" "both")])
17677 (define_insn "*strmovsi_1"
17678   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17679         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17680    (set (match_operand:SI 0 "register_operand" "=D")
17681         (plus:SI (match_dup 2)
17682                  (const_int 4)))
17683    (set (match_operand:SI 1 "register_operand" "=S")
17684         (plus:SI (match_dup 3)
17685                  (const_int 4)))]
17686   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17687   "{movsl|movsd}"
17688   [(set_attr "type" "str")
17689    (set_attr "mode" "SI")
17690    (set_attr "memory" "both")])
17692 (define_insn "*strmovsi_rex_1"
17693   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17694         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17695    (set (match_operand:DI 0 "register_operand" "=D")
17696         (plus:DI (match_dup 2)
17697                  (const_int 4)))
17698    (set (match_operand:DI 1 "register_operand" "=S")
17699         (plus:DI (match_dup 3)
17700                  (const_int 4)))]
17701   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17702   "{movsl|movsd}"
17703   [(set_attr "type" "str")
17704    (set_attr "mode" "SI")
17705    (set_attr "memory" "both")])
17707 (define_insn "*strmovhi_1"
17708   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17709         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17710    (set (match_operand:SI 0 "register_operand" "=D")
17711         (plus:SI (match_dup 2)
17712                  (const_int 2)))
17713    (set (match_operand:SI 1 "register_operand" "=S")
17714         (plus:SI (match_dup 3)
17715                  (const_int 2)))]
17716   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17717   "movsw"
17718   [(set_attr "type" "str")
17719    (set_attr "memory" "both")
17720    (set_attr "mode" "HI")])
17722 (define_insn "*strmovhi_rex_1"
17723   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17724         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17725    (set (match_operand:DI 0 "register_operand" "=D")
17726         (plus:DI (match_dup 2)
17727                  (const_int 2)))
17728    (set (match_operand:DI 1 "register_operand" "=S")
17729         (plus:DI (match_dup 3)
17730                  (const_int 2)))]
17731   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17732   "movsw"
17733   [(set_attr "type" "str")
17734    (set_attr "memory" "both")
17735    (set_attr "mode" "HI")])
17737 (define_insn "*strmovqi_1"
17738   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17739         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17740    (set (match_operand:SI 0 "register_operand" "=D")
17741         (plus:SI (match_dup 2)
17742                  (const_int 1)))
17743    (set (match_operand:SI 1 "register_operand" "=S")
17744         (plus:SI (match_dup 3)
17745                  (const_int 1)))]
17746   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17747   "movsb"
17748   [(set_attr "type" "str")
17749    (set_attr "memory" "both")
17750    (set_attr "mode" "QI")])
17752 (define_insn "*strmovqi_rex_1"
17753   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17754         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17755    (set (match_operand:DI 0 "register_operand" "=D")
17756         (plus:DI (match_dup 2)
17757                  (const_int 1)))
17758    (set (match_operand:DI 1 "register_operand" "=S")
17759         (plus:DI (match_dup 3)
17760                  (const_int 1)))]
17761   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17762   "movsb"
17763   [(set_attr "type" "str")
17764    (set_attr "memory" "both")
17765    (set_attr "mode" "QI")])
17767 (define_expand "rep_mov"
17768   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17769               (set (match_operand 0 "register_operand" "")
17770                    (match_operand 5 "" ""))
17771               (set (match_operand 2 "register_operand" "")
17772                    (match_operand 6 "" ""))
17773               (set (match_operand 1 "memory_operand" "")
17774                    (match_operand 3 "memory_operand" ""))
17775               (use (match_dup 4))])]
17776   ""
17777   "")
17779 (define_insn "*rep_movdi_rex64"
17780   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17781    (set (match_operand:DI 0 "register_operand" "=D")
17782         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17783                             (const_int 3))
17784                  (match_operand:DI 3 "register_operand" "0")))
17785    (set (match_operand:DI 1 "register_operand" "=S")
17786         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17787                  (match_operand:DI 4 "register_operand" "1")))
17788    (set (mem:BLK (match_dup 3))
17789         (mem:BLK (match_dup 4)))
17790    (use (match_dup 5))]
17791   "TARGET_64BIT"
17792   "{rep\;movsq|rep movsq}"
17793   [(set_attr "type" "str")
17794    (set_attr "prefix_rep" "1")
17795    (set_attr "memory" "both")
17796    (set_attr "mode" "DI")])
17798 (define_insn "*rep_movsi"
17799   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17800    (set (match_operand:SI 0 "register_operand" "=D")
17801         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17802                             (const_int 2))
17803                  (match_operand:SI 3 "register_operand" "0")))
17804    (set (match_operand:SI 1 "register_operand" "=S")
17805         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17806                  (match_operand:SI 4 "register_operand" "1")))
17807    (set (mem:BLK (match_dup 3))
17808         (mem:BLK (match_dup 4)))
17809    (use (match_dup 5))]
17810   "!TARGET_64BIT"
17811   "{rep\;movsl|rep movsd}"
17812   [(set_attr "type" "str")
17813    (set_attr "prefix_rep" "1")
17814    (set_attr "memory" "both")
17815    (set_attr "mode" "SI")])
17817 (define_insn "*rep_movsi_rex64"
17818   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17819    (set (match_operand:DI 0 "register_operand" "=D")
17820         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17821                             (const_int 2))
17822                  (match_operand:DI 3 "register_operand" "0")))
17823    (set (match_operand:DI 1 "register_operand" "=S")
17824         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17825                  (match_operand:DI 4 "register_operand" "1")))
17826    (set (mem:BLK (match_dup 3))
17827         (mem:BLK (match_dup 4)))
17828    (use (match_dup 5))]
17829   "TARGET_64BIT"
17830   "{rep\;movsl|rep movsd}"
17831   [(set_attr "type" "str")
17832    (set_attr "prefix_rep" "1")
17833    (set_attr "memory" "both")
17834    (set_attr "mode" "SI")])
17836 (define_insn "*rep_movqi"
17837   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17838    (set (match_operand:SI 0 "register_operand" "=D")
17839         (plus:SI (match_operand:SI 3 "register_operand" "0")
17840                  (match_operand:SI 5 "register_operand" "2")))
17841    (set (match_operand:SI 1 "register_operand" "=S")
17842         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17843    (set (mem:BLK (match_dup 3))
17844         (mem:BLK (match_dup 4)))
17845    (use (match_dup 5))]
17846   "!TARGET_64BIT"
17847   "{rep\;movsb|rep movsb}"
17848   [(set_attr "type" "str")
17849    (set_attr "prefix_rep" "1")
17850    (set_attr "memory" "both")
17851    (set_attr "mode" "SI")])
17853 (define_insn "*rep_movqi_rex64"
17854   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17855    (set (match_operand:DI 0 "register_operand" "=D")
17856         (plus:DI (match_operand:DI 3 "register_operand" "0")
17857                  (match_operand:DI 5 "register_operand" "2")))
17858    (set (match_operand:DI 1 "register_operand" "=S")
17859         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17860    (set (mem:BLK (match_dup 3))
17861         (mem:BLK (match_dup 4)))
17862    (use (match_dup 5))]
17863   "TARGET_64BIT"
17864   "{rep\;movsb|rep movsb}"
17865   [(set_attr "type" "str")
17866    (set_attr "prefix_rep" "1")
17867    (set_attr "memory" "both")
17868    (set_attr "mode" "SI")])
17870 (define_expand "setmemsi"
17871    [(use (match_operand:BLK 0 "memory_operand" ""))
17872     (use (match_operand:SI 1 "nonmemory_operand" ""))
17873     (use (match_operand 2 "const_int_operand" ""))
17874     (use (match_operand 3 "const_int_operand" ""))
17875     (use (match_operand:SI 4 "const_int_operand" ""))
17876     (use (match_operand:SI 5 "const_int_operand" ""))]
17877   ""
17879  if (ix86_expand_setmem (operands[0], operands[1],
17880                          operands[2], operands[3],
17881                          operands[4], operands[5]))
17882    DONE;
17883  else
17884    FAIL;
17887 (define_expand "setmemdi"
17888    [(use (match_operand:BLK 0 "memory_operand" ""))
17889     (use (match_operand:DI 1 "nonmemory_operand" ""))
17890     (use (match_operand 2 "const_int_operand" ""))
17891     (use (match_operand 3 "const_int_operand" ""))
17892     (use (match_operand 4 "const_int_operand" ""))
17893     (use (match_operand 5 "const_int_operand" ""))]
17894   "TARGET_64BIT"
17896  if (ix86_expand_setmem (operands[0], operands[1],
17897                          operands[2], operands[3],
17898                          operands[4], operands[5]))
17899    DONE;
17900  else
17901    FAIL;
17904 ;; Most CPUs don't like single string operations
17905 ;; Handle this case here to simplify previous expander.
17907 (define_expand "strset"
17908   [(set (match_operand 1 "memory_operand" "")
17909         (match_operand 2 "register_operand" ""))
17910    (parallel [(set (match_operand 0 "register_operand" "")
17911                    (match_dup 3))
17912               (clobber (reg:CC FLAGS_REG))])]
17913   ""
17915   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17916     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17918   /* If .md ever supports :P for Pmode, this can be directly
17919      in the pattern above.  */
17920   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17921                               GEN_INT (GET_MODE_SIZE (GET_MODE
17922                                                       (operands[2]))));
17923   if (TARGET_SINGLE_STRINGOP || optimize_size)
17924     {
17925       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17926                                       operands[3]));
17927       DONE;
17928     }
17931 (define_expand "strset_singleop"
17932   [(parallel [(set (match_operand 1 "memory_operand" "")
17933                    (match_operand 2 "register_operand" ""))
17934               (set (match_operand 0 "register_operand" "")
17935                    (match_operand 3 "" ""))])]
17936   "TARGET_SINGLE_STRINGOP || optimize_size"
17937   "")
17939 (define_insn "*strsetdi_rex_1"
17940   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17941         (match_operand:DI 2 "register_operand" "a"))
17942    (set (match_operand:DI 0 "register_operand" "=D")
17943         (plus:DI (match_dup 1)
17944                  (const_int 8)))]
17945   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17946   "stosq"
17947   [(set_attr "type" "str")
17948    (set_attr "memory" "store")
17949    (set_attr "mode" "DI")])
17951 (define_insn "*strsetsi_1"
17952   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17953         (match_operand:SI 2 "register_operand" "a"))
17954    (set (match_operand:SI 0 "register_operand" "=D")
17955         (plus:SI (match_dup 1)
17956                  (const_int 4)))]
17957   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17958   "{stosl|stosd}"
17959   [(set_attr "type" "str")
17960    (set_attr "memory" "store")
17961    (set_attr "mode" "SI")])
17963 (define_insn "*strsetsi_rex_1"
17964   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17965         (match_operand:SI 2 "register_operand" "a"))
17966    (set (match_operand:DI 0 "register_operand" "=D")
17967         (plus:DI (match_dup 1)
17968                  (const_int 4)))]
17969   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17970   "{stosl|stosd}"
17971   [(set_attr "type" "str")
17972    (set_attr "memory" "store")
17973    (set_attr "mode" "SI")])
17975 (define_insn "*strsethi_1"
17976   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17977         (match_operand:HI 2 "register_operand" "a"))
17978    (set (match_operand:SI 0 "register_operand" "=D")
17979         (plus:SI (match_dup 1)
17980                  (const_int 2)))]
17981   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17982   "stosw"
17983   [(set_attr "type" "str")
17984    (set_attr "memory" "store")
17985    (set_attr "mode" "HI")])
17987 (define_insn "*strsethi_rex_1"
17988   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17989         (match_operand:HI 2 "register_operand" "a"))
17990    (set (match_operand:DI 0 "register_operand" "=D")
17991         (plus:DI (match_dup 1)
17992                  (const_int 2)))]
17993   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17994   "stosw"
17995   [(set_attr "type" "str")
17996    (set_attr "memory" "store")
17997    (set_attr "mode" "HI")])
17999 (define_insn "*strsetqi_1"
18000   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18001         (match_operand:QI 2 "register_operand" "a"))
18002    (set (match_operand:SI 0 "register_operand" "=D")
18003         (plus:SI (match_dup 1)
18004                  (const_int 1)))]
18005   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18006   "stosb"
18007   [(set_attr "type" "str")
18008    (set_attr "memory" "store")
18009    (set_attr "mode" "QI")])
18011 (define_insn "*strsetqi_rex_1"
18012   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18013         (match_operand:QI 2 "register_operand" "a"))
18014    (set (match_operand:DI 0 "register_operand" "=D")
18015         (plus:DI (match_dup 1)
18016                  (const_int 1)))]
18017   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18018   "stosb"
18019   [(set_attr "type" "str")
18020    (set_attr "memory" "store")
18021    (set_attr "mode" "QI")])
18023 (define_expand "rep_stos"
18024   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18025               (set (match_operand 0 "register_operand" "")
18026                    (match_operand 4 "" ""))
18027               (set (match_operand 2 "memory_operand" "") (const_int 0))
18028               (use (match_operand 3 "register_operand" ""))
18029               (use (match_dup 1))])]
18030   ""
18031   "")
18033 (define_insn "*rep_stosdi_rex64"
18034   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18035    (set (match_operand:DI 0 "register_operand" "=D")
18036         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18037                             (const_int 3))
18038                  (match_operand:DI 3 "register_operand" "0")))
18039    (set (mem:BLK (match_dup 3))
18040         (const_int 0))
18041    (use (match_operand:DI 2 "register_operand" "a"))
18042    (use (match_dup 4))]
18043   "TARGET_64BIT"
18044   "{rep\;stosq|rep stosq}"
18045   [(set_attr "type" "str")
18046    (set_attr "prefix_rep" "1")
18047    (set_attr "memory" "store")
18048    (set_attr "mode" "DI")])
18050 (define_insn "*rep_stossi"
18051   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18052    (set (match_operand:SI 0 "register_operand" "=D")
18053         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18054                             (const_int 2))
18055                  (match_operand:SI 3 "register_operand" "0")))
18056    (set (mem:BLK (match_dup 3))
18057         (const_int 0))
18058    (use (match_operand:SI 2 "register_operand" "a"))
18059    (use (match_dup 4))]
18060   "!TARGET_64BIT"
18061   "{rep\;stosl|rep stosd}"
18062   [(set_attr "type" "str")
18063    (set_attr "prefix_rep" "1")
18064    (set_attr "memory" "store")
18065    (set_attr "mode" "SI")])
18067 (define_insn "*rep_stossi_rex64"
18068   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18069    (set (match_operand:DI 0 "register_operand" "=D")
18070         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18071                             (const_int 2))
18072                  (match_operand:DI 3 "register_operand" "0")))
18073    (set (mem:BLK (match_dup 3))
18074         (const_int 0))
18075    (use (match_operand:SI 2 "register_operand" "a"))
18076    (use (match_dup 4))]
18077   "TARGET_64BIT"
18078   "{rep\;stosl|rep stosd}"
18079   [(set_attr "type" "str")
18080    (set_attr "prefix_rep" "1")
18081    (set_attr "memory" "store")
18082    (set_attr "mode" "SI")])
18084 (define_insn "*rep_stosqi"
18085   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18086    (set (match_operand:SI 0 "register_operand" "=D")
18087         (plus:SI (match_operand:SI 3 "register_operand" "0")
18088                  (match_operand:SI 4 "register_operand" "1")))
18089    (set (mem:BLK (match_dup 3))
18090         (const_int 0))
18091    (use (match_operand:QI 2 "register_operand" "a"))
18092    (use (match_dup 4))]
18093   "!TARGET_64BIT"
18094   "{rep\;stosb|rep stosb}"
18095   [(set_attr "type" "str")
18096    (set_attr "prefix_rep" "1")
18097    (set_attr "memory" "store")
18098    (set_attr "mode" "QI")])
18100 (define_insn "*rep_stosqi_rex64"
18101   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18102    (set (match_operand:DI 0 "register_operand" "=D")
18103         (plus:DI (match_operand:DI 3 "register_operand" "0")
18104                  (match_operand:DI 4 "register_operand" "1")))
18105    (set (mem:BLK (match_dup 3))
18106         (const_int 0))
18107    (use (match_operand:QI 2 "register_operand" "a"))
18108    (use (match_dup 4))]
18109   "TARGET_64BIT"
18110   "{rep\;stosb|rep stosb}"
18111   [(set_attr "type" "str")
18112    (set_attr "prefix_rep" "1")
18113    (set_attr "memory" "store")
18114    (set_attr "mode" "QI")])
18116 (define_expand "cmpstrnsi"
18117   [(set (match_operand:SI 0 "register_operand" "")
18118         (compare:SI (match_operand:BLK 1 "general_operand" "")
18119                     (match_operand:BLK 2 "general_operand" "")))
18120    (use (match_operand 3 "general_operand" ""))
18121    (use (match_operand 4 "immediate_operand" ""))]
18122   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18124   rtx addr1, addr2, out, outlow, count, countreg, align;
18126   /* Can't use this if the user has appropriated esi or edi.  */
18127   if (global_regs[4] || global_regs[5])
18128     FAIL;
18130   out = operands[0];
18131   if (!REG_P (out))
18132     out = gen_reg_rtx (SImode);
18134   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18135   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18136   if (addr1 != XEXP (operands[1], 0))
18137     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18138   if (addr2 != XEXP (operands[2], 0))
18139     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18141   count = operands[3];
18142   countreg = ix86_zero_extend_to_Pmode (count);
18144   /* %%% Iff we are testing strict equality, we can use known alignment
18145      to good advantage.  This may be possible with combine, particularly
18146      once cc0 is dead.  */
18147   align = operands[4];
18149   if (CONST_INT_P (count))
18150     {
18151       if (INTVAL (count) == 0)
18152         {
18153           emit_move_insn (operands[0], const0_rtx);
18154           DONE;
18155         }
18156       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18157                                      operands[1], operands[2]));
18158     }
18159   else
18160     {
18161       if (TARGET_64BIT)
18162         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18163       else
18164         emit_insn (gen_cmpsi_1 (countreg, countreg));
18165       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18166                                   operands[1], operands[2]));
18167     }
18169   outlow = gen_lowpart (QImode, out);
18170   emit_insn (gen_cmpintqi (outlow));
18171   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18173   if (operands[0] != out)
18174     emit_move_insn (operands[0], out);
18176   DONE;
18179 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18181 (define_expand "cmpintqi"
18182   [(set (match_dup 1)
18183         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18184    (set (match_dup 2)
18185         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18186    (parallel [(set (match_operand:QI 0 "register_operand" "")
18187                    (minus:QI (match_dup 1)
18188                              (match_dup 2)))
18189               (clobber (reg:CC FLAGS_REG))])]
18190   ""
18191   "operands[1] = gen_reg_rtx (QImode);
18192    operands[2] = gen_reg_rtx (QImode);")
18194 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18195 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18197 (define_expand "cmpstrnqi_nz_1"
18198   [(parallel [(set (reg:CC FLAGS_REG)
18199                    (compare:CC (match_operand 4 "memory_operand" "")
18200                                (match_operand 5 "memory_operand" "")))
18201               (use (match_operand 2 "register_operand" ""))
18202               (use (match_operand:SI 3 "immediate_operand" ""))
18203               (clobber (match_operand 0 "register_operand" ""))
18204               (clobber (match_operand 1 "register_operand" ""))
18205               (clobber (match_dup 2))])]
18206   ""
18207   "")
18209 (define_insn "*cmpstrnqi_nz_1"
18210   [(set (reg:CC FLAGS_REG)
18211         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18212                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18213    (use (match_operand:SI 6 "register_operand" "2"))
18214    (use (match_operand:SI 3 "immediate_operand" "i"))
18215    (clobber (match_operand:SI 0 "register_operand" "=S"))
18216    (clobber (match_operand:SI 1 "register_operand" "=D"))
18217    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18218   "!TARGET_64BIT"
18219   "repz{\;| }cmpsb"
18220   [(set_attr "type" "str")
18221    (set_attr "mode" "QI")
18222    (set_attr "prefix_rep" "1")])
18224 (define_insn "*cmpstrnqi_nz_rex_1"
18225   [(set (reg:CC FLAGS_REG)
18226         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18227                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18228    (use (match_operand:DI 6 "register_operand" "2"))
18229    (use (match_operand:SI 3 "immediate_operand" "i"))
18230    (clobber (match_operand:DI 0 "register_operand" "=S"))
18231    (clobber (match_operand:DI 1 "register_operand" "=D"))
18232    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18233   "TARGET_64BIT"
18234   "repz{\;| }cmpsb"
18235   [(set_attr "type" "str")
18236    (set_attr "mode" "QI")
18237    (set_attr "prefix_rep" "1")])
18239 ;; The same, but the count is not known to not be zero.
18241 (define_expand "cmpstrnqi_1"
18242   [(parallel [(set (reg:CC FLAGS_REG)
18243                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18244                                      (const_int 0))
18245                   (compare:CC (match_operand 4 "memory_operand" "")
18246                               (match_operand 5 "memory_operand" ""))
18247                   (const_int 0)))
18248               (use (match_operand:SI 3 "immediate_operand" ""))
18249               (use (reg:CC FLAGS_REG))
18250               (clobber (match_operand 0 "register_operand" ""))
18251               (clobber (match_operand 1 "register_operand" ""))
18252               (clobber (match_dup 2))])]
18253   ""
18254   "")
18256 (define_insn "*cmpstrnqi_1"
18257   [(set (reg:CC FLAGS_REG)
18258         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18259                              (const_int 0))
18260           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18261                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18262           (const_int 0)))
18263    (use (match_operand:SI 3 "immediate_operand" "i"))
18264    (use (reg:CC FLAGS_REG))
18265    (clobber (match_operand:SI 0 "register_operand" "=S"))
18266    (clobber (match_operand:SI 1 "register_operand" "=D"))
18267    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18268   "!TARGET_64BIT"
18269   "repz{\;| }cmpsb"
18270   [(set_attr "type" "str")
18271    (set_attr "mode" "QI")
18272    (set_attr "prefix_rep" "1")])
18274 (define_insn "*cmpstrnqi_rex_1"
18275   [(set (reg:CC FLAGS_REG)
18276         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18277                              (const_int 0))
18278           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18279                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18280           (const_int 0)))
18281    (use (match_operand:SI 3 "immediate_operand" "i"))
18282    (use (reg:CC FLAGS_REG))
18283    (clobber (match_operand:DI 0 "register_operand" "=S"))
18284    (clobber (match_operand:DI 1 "register_operand" "=D"))
18285    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18286   "TARGET_64BIT"
18287   "repz{\;| }cmpsb"
18288   [(set_attr "type" "str")
18289    (set_attr "mode" "QI")
18290    (set_attr "prefix_rep" "1")])
18292 (define_expand "strlensi"
18293   [(set (match_operand:SI 0 "register_operand" "")
18294         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18295                     (match_operand:QI 2 "immediate_operand" "")
18296                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18297   ""
18299  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18300    DONE;
18301  else
18302    FAIL;
18305 (define_expand "strlendi"
18306   [(set (match_operand:DI 0 "register_operand" "")
18307         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18308                     (match_operand:QI 2 "immediate_operand" "")
18309                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18310   ""
18312  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18313    DONE;
18314  else
18315    FAIL;
18318 (define_expand "strlenqi_1"
18319   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18320               (clobber (match_operand 1 "register_operand" ""))
18321               (clobber (reg:CC FLAGS_REG))])]
18322   ""
18323   "")
18325 (define_insn "*strlenqi_1"
18326   [(set (match_operand:SI 0 "register_operand" "=&c")
18327         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18328                     (match_operand:QI 2 "register_operand" "a")
18329                     (match_operand:SI 3 "immediate_operand" "i")
18330                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18331    (clobber (match_operand:SI 1 "register_operand" "=D"))
18332    (clobber (reg:CC FLAGS_REG))]
18333   "!TARGET_64BIT"
18334   "repnz{\;| }scasb"
18335   [(set_attr "type" "str")
18336    (set_attr "mode" "QI")
18337    (set_attr "prefix_rep" "1")])
18339 (define_insn "*strlenqi_rex_1"
18340   [(set (match_operand:DI 0 "register_operand" "=&c")
18341         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18342                     (match_operand:QI 2 "register_operand" "a")
18343                     (match_operand:DI 3 "immediate_operand" "i")
18344                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18345    (clobber (match_operand:DI 1 "register_operand" "=D"))
18346    (clobber (reg:CC FLAGS_REG))]
18347   "TARGET_64BIT"
18348   "repnz{\;| }scasb"
18349   [(set_attr "type" "str")
18350    (set_attr "mode" "QI")
18351    (set_attr "prefix_rep" "1")])
18353 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18354 ;; handled in combine, but it is not currently up to the task.
18355 ;; When used for their truth value, the cmpstrn* expanders generate
18356 ;; code like this:
18358 ;;   repz cmpsb
18359 ;;   seta       %al
18360 ;;   setb       %dl
18361 ;;   cmpb       %al, %dl
18362 ;;   jcc        label
18364 ;; The intermediate three instructions are unnecessary.
18366 ;; This one handles cmpstrn*_nz_1...
18367 (define_peephole2
18368   [(parallel[
18369      (set (reg:CC FLAGS_REG)
18370           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18371                       (mem:BLK (match_operand 5 "register_operand" ""))))
18372      (use (match_operand 6 "register_operand" ""))
18373      (use (match_operand:SI 3 "immediate_operand" ""))
18374      (clobber (match_operand 0 "register_operand" ""))
18375      (clobber (match_operand 1 "register_operand" ""))
18376      (clobber (match_operand 2 "register_operand" ""))])
18377    (set (match_operand:QI 7 "register_operand" "")
18378         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18379    (set (match_operand:QI 8 "register_operand" "")
18380         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18381    (set (reg FLAGS_REG)
18382         (compare (match_dup 7) (match_dup 8)))
18383   ]
18384   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18385   [(parallel[
18386      (set (reg:CC FLAGS_REG)
18387           (compare:CC (mem:BLK (match_dup 4))
18388                       (mem:BLK (match_dup 5))))
18389      (use (match_dup 6))
18390      (use (match_dup 3))
18391      (clobber (match_dup 0))
18392      (clobber (match_dup 1))
18393      (clobber (match_dup 2))])]
18394   "")
18396 ;; ...and this one handles cmpstrn*_1.
18397 (define_peephole2
18398   [(parallel[
18399      (set (reg:CC FLAGS_REG)
18400           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18401                                (const_int 0))
18402             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18403                         (mem:BLK (match_operand 5 "register_operand" "")))
18404             (const_int 0)))
18405      (use (match_operand:SI 3 "immediate_operand" ""))
18406      (use (reg:CC FLAGS_REG))
18407      (clobber (match_operand 0 "register_operand" ""))
18408      (clobber (match_operand 1 "register_operand" ""))
18409      (clobber (match_operand 2 "register_operand" ""))])
18410    (set (match_operand:QI 7 "register_operand" "")
18411         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18412    (set (match_operand:QI 8 "register_operand" "")
18413         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18414    (set (reg FLAGS_REG)
18415         (compare (match_dup 7) (match_dup 8)))
18416   ]
18417   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18418   [(parallel[
18419      (set (reg:CC FLAGS_REG)
18420           (if_then_else:CC (ne (match_dup 6)
18421                                (const_int 0))
18422             (compare:CC (mem:BLK (match_dup 4))
18423                         (mem:BLK (match_dup 5)))
18424             (const_int 0)))
18425      (use (match_dup 3))
18426      (use (reg:CC FLAGS_REG))
18427      (clobber (match_dup 0))
18428      (clobber (match_dup 1))
18429      (clobber (match_dup 2))])]
18430   "")
18434 ;; Conditional move instructions.
18436 (define_expand "movdicc"
18437   [(set (match_operand:DI 0 "register_operand" "")
18438         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18439                          (match_operand:DI 2 "general_operand" "")
18440                          (match_operand:DI 3 "general_operand" "")))]
18441   "TARGET_64BIT"
18442   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18444 (define_insn "x86_movdicc_0_m1_rex64"
18445   [(set (match_operand:DI 0 "register_operand" "=r")
18446         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18447           (const_int -1)
18448           (const_int 0)))
18449    (clobber (reg:CC FLAGS_REG))]
18450   "TARGET_64BIT"
18451   "sbb{q}\t%0, %0"
18452   ; Since we don't have the proper number of operands for an alu insn,
18453   ; fill in all the blanks.
18454   [(set_attr "type" "alu")
18455    (set_attr "pent_pair" "pu")
18456    (set_attr "memory" "none")
18457    (set_attr "imm_disp" "false")
18458    (set_attr "mode" "DI")
18459    (set_attr "length_immediate" "0")])
18461 (define_insn "*movdicc_c_rex64"
18462   [(set (match_operand:DI 0 "register_operand" "=r,r")
18463         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18464                                 [(reg FLAGS_REG) (const_int 0)])
18465                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18466                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18467   "TARGET_64BIT && TARGET_CMOVE
18468    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18469   "@
18470    cmov%O2%C1\t{%2, %0|%0, %2}
18471    cmov%O2%c1\t{%3, %0|%0, %3}"
18472   [(set_attr "type" "icmov")
18473    (set_attr "mode" "DI")])
18475 (define_expand "movsicc"
18476   [(set (match_operand:SI 0 "register_operand" "")
18477         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18478                          (match_operand:SI 2 "general_operand" "")
18479                          (match_operand:SI 3 "general_operand" "")))]
18480   ""
18481   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18483 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18484 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18485 ;; So just document what we're doing explicitly.
18487 (define_insn "x86_movsicc_0_m1"
18488   [(set (match_operand:SI 0 "register_operand" "=r")
18489         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18490           (const_int -1)
18491           (const_int 0)))
18492    (clobber (reg:CC FLAGS_REG))]
18493   ""
18494   "sbb{l}\t%0, %0"
18495   ; Since we don't have the proper number of operands for an alu insn,
18496   ; fill in all the blanks.
18497   [(set_attr "type" "alu")
18498    (set_attr "pent_pair" "pu")
18499    (set_attr "memory" "none")
18500    (set_attr "imm_disp" "false")
18501    (set_attr "mode" "SI")
18502    (set_attr "length_immediate" "0")])
18504 (define_insn "*movsicc_noc"
18505   [(set (match_operand:SI 0 "register_operand" "=r,r")
18506         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18507                                 [(reg FLAGS_REG) (const_int 0)])
18508                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18509                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18510   "TARGET_CMOVE
18511    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18512   "@
18513    cmov%O2%C1\t{%2, %0|%0, %2}
18514    cmov%O2%c1\t{%3, %0|%0, %3}"
18515   [(set_attr "type" "icmov")
18516    (set_attr "mode" "SI")])
18518 (define_expand "movhicc"
18519   [(set (match_operand:HI 0 "register_operand" "")
18520         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18521                          (match_operand:HI 2 "general_operand" "")
18522                          (match_operand:HI 3 "general_operand" "")))]
18523   "TARGET_HIMODE_MATH"
18524   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18526 (define_insn "*movhicc_noc"
18527   [(set (match_operand:HI 0 "register_operand" "=r,r")
18528         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18529                                 [(reg FLAGS_REG) (const_int 0)])
18530                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18531                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18532   "TARGET_CMOVE
18533    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18534   "@
18535    cmov%O2%C1\t{%2, %0|%0, %2}
18536    cmov%O2%c1\t{%3, %0|%0, %3}"
18537   [(set_attr "type" "icmov")
18538    (set_attr "mode" "HI")])
18540 (define_expand "movqicc"
18541   [(set (match_operand:QI 0 "register_operand" "")
18542         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18543                          (match_operand:QI 2 "general_operand" "")
18544                          (match_operand:QI 3 "general_operand" "")))]
18545   "TARGET_QIMODE_MATH"
18546   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18548 (define_insn_and_split "*movqicc_noc"
18549   [(set (match_operand:QI 0 "register_operand" "=r,r")
18550         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18551                                 [(match_operand 4 "flags_reg_operand" "")
18552                                  (const_int 0)])
18553                       (match_operand:QI 2 "register_operand" "r,0")
18554                       (match_operand:QI 3 "register_operand" "0,r")))]
18555   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18556   "#"
18557   "&& reload_completed"
18558   [(set (match_dup 0)
18559         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18560                       (match_dup 2)
18561                       (match_dup 3)))]
18562   "operands[0] = gen_lowpart (SImode, operands[0]);
18563    operands[2] = gen_lowpart (SImode, operands[2]);
18564    operands[3] = gen_lowpart (SImode, operands[3]);"
18565   [(set_attr "type" "icmov")
18566    (set_attr "mode" "SI")])
18568 (define_expand "movsfcc"
18569   [(set (match_operand:SF 0 "register_operand" "")
18570         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18571                          (match_operand:SF 2 "register_operand" "")
18572                          (match_operand:SF 3 "register_operand" "")))]
18573   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18574   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18576 (define_insn "*movsfcc_1_387"
18577   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18578         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18579                                 [(reg FLAGS_REG) (const_int 0)])
18580                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18581                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18582   "TARGET_80387 && TARGET_CMOVE
18583    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18584   "@
18585    fcmov%F1\t{%2, %0|%0, %2}
18586    fcmov%f1\t{%3, %0|%0, %3}
18587    cmov%O2%C1\t{%2, %0|%0, %2}
18588    cmov%O2%c1\t{%3, %0|%0, %3}"
18589   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18590    (set_attr "mode" "SF,SF,SI,SI")])
18592 (define_expand "movdfcc"
18593   [(set (match_operand:DF 0 "register_operand" "")
18594         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18595                          (match_operand:DF 2 "register_operand" "")
18596                          (match_operand:DF 3 "register_operand" "")))]
18597   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18598   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18600 (define_insn "*movdfcc_1"
18601   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18602         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18603                                 [(reg FLAGS_REG) (const_int 0)])
18604                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18605                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18606   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18607    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18608   "@
18609    fcmov%F1\t{%2, %0|%0, %2}
18610    fcmov%f1\t{%3, %0|%0, %3}
18611    #
18612    #"
18613   [(set_attr "type" "fcmov,fcmov,multi,multi")
18614    (set_attr "mode" "DF")])
18616 (define_insn "*movdfcc_1_rex64"
18617   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18618         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18619                                 [(reg FLAGS_REG) (const_int 0)])
18620                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18621                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18622   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18623    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18624   "@
18625    fcmov%F1\t{%2, %0|%0, %2}
18626    fcmov%f1\t{%3, %0|%0, %3}
18627    cmov%O2%C1\t{%2, %0|%0, %2}
18628    cmov%O2%c1\t{%3, %0|%0, %3}"
18629   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18630    (set_attr "mode" "DF")])
18632 (define_split
18633   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18634         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18635                                 [(match_operand 4 "flags_reg_operand" "")
18636                                  (const_int 0)])
18637                       (match_operand:DF 2 "nonimmediate_operand" "")
18638                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18639   "!TARGET_64BIT && reload_completed"
18640   [(set (match_dup 2)
18641         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18642                       (match_dup 5)
18643                       (match_dup 7)))
18644    (set (match_dup 3)
18645         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18646                       (match_dup 6)
18647                       (match_dup 8)))]
18648   "split_di (operands+2, 1, operands+5, operands+6);
18649    split_di (operands+3, 1, operands+7, operands+8);
18650    split_di (operands, 1, operands+2, operands+3);")
18652 (define_expand "movxfcc"
18653   [(set (match_operand:XF 0 "register_operand" "")
18654         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18655                          (match_operand:XF 2 "register_operand" "")
18656                          (match_operand:XF 3 "register_operand" "")))]
18657   "TARGET_80387 && TARGET_CMOVE"
18658   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18660 (define_insn "*movxfcc_1"
18661   [(set (match_operand:XF 0 "register_operand" "=f,f")
18662         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18663                                 [(reg FLAGS_REG) (const_int 0)])
18664                       (match_operand:XF 2 "register_operand" "f,0")
18665                       (match_operand:XF 3 "register_operand" "0,f")))]
18666   "TARGET_80387 && TARGET_CMOVE"
18667   "@
18668    fcmov%F1\t{%2, %0|%0, %2}
18669    fcmov%f1\t{%3, %0|%0, %3}"
18670   [(set_attr "type" "fcmov")
18671    (set_attr "mode" "XF")])
18673 ;; These versions of the min/max patterns are intentionally ignorant of
18674 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18675 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18676 ;; are undefined in this condition, we're certain this is correct.
18678 (define_insn "sminsf3"
18679   [(set (match_operand:SF 0 "register_operand" "=x")
18680         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18681                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18682   "TARGET_SSE_MATH"
18683   "minss\t{%2, %0|%0, %2}"
18684   [(set_attr "type" "sseadd")
18685    (set_attr "mode" "SF")])
18687 (define_insn "smaxsf3"
18688   [(set (match_operand:SF 0 "register_operand" "=x")
18689         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18690                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18691   "TARGET_SSE_MATH"
18692   "maxss\t{%2, %0|%0, %2}"
18693   [(set_attr "type" "sseadd")
18694    (set_attr "mode" "SF")])
18696 (define_insn "smindf3"
18697   [(set (match_operand:DF 0 "register_operand" "=x")
18698         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18699                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18700   "TARGET_SSE2 && TARGET_SSE_MATH"
18701   "minsd\t{%2, %0|%0, %2}"
18702   [(set_attr "type" "sseadd")
18703    (set_attr "mode" "DF")])
18705 (define_insn "smaxdf3"
18706   [(set (match_operand:DF 0 "register_operand" "=x")
18707         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18708                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18709   "TARGET_SSE2 && TARGET_SSE_MATH"
18710   "maxsd\t{%2, %0|%0, %2}"
18711   [(set_attr "type" "sseadd")
18712    (set_attr "mode" "DF")])
18714 ;; These versions of the min/max patterns implement exactly the operations
18715 ;;   min = (op1 < op2 ? op1 : op2)
18716 ;;   max = (!(op1 < op2) ? op1 : op2)
18717 ;; Their operands are not commutative, and thus they may be used in the
18718 ;; presence of -0.0 and NaN.
18720 (define_insn "*ieee_sminsf3"
18721   [(set (match_operand:SF 0 "register_operand" "=x")
18722         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18723                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18724                    UNSPEC_IEEE_MIN))]
18725   "TARGET_SSE_MATH"
18726   "minss\t{%2, %0|%0, %2}"
18727   [(set_attr "type" "sseadd")
18728    (set_attr "mode" "SF")])
18730 (define_insn "*ieee_smaxsf3"
18731   [(set (match_operand:SF 0 "register_operand" "=x")
18732         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18733                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18734                    UNSPEC_IEEE_MAX))]
18735   "TARGET_SSE_MATH"
18736   "maxss\t{%2, %0|%0, %2}"
18737   [(set_attr "type" "sseadd")
18738    (set_attr "mode" "SF")])
18740 (define_insn "*ieee_smindf3"
18741   [(set (match_operand:DF 0 "register_operand" "=x")
18742         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18743                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18744                    UNSPEC_IEEE_MIN))]
18745   "TARGET_SSE2 && TARGET_SSE_MATH"
18746   "minsd\t{%2, %0|%0, %2}"
18747   [(set_attr "type" "sseadd")
18748    (set_attr "mode" "DF")])
18750 (define_insn "*ieee_smaxdf3"
18751   [(set (match_operand:DF 0 "register_operand" "=x")
18752         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18753                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18754                    UNSPEC_IEEE_MAX))]
18755   "TARGET_SSE2 && TARGET_SSE_MATH"
18756   "maxsd\t{%2, %0|%0, %2}"
18757   [(set_attr "type" "sseadd")
18758    (set_attr "mode" "DF")])
18760 ;; Make two stack loads independent:
18761 ;;   fld aa              fld aa
18762 ;;   fld %st(0)     ->   fld bb
18763 ;;   fmul bb             fmul %st(1), %st
18765 ;; Actually we only match the last two instructions for simplicity.
18766 (define_peephole2
18767   [(set (match_operand 0 "fp_register_operand" "")
18768         (match_operand 1 "fp_register_operand" ""))
18769    (set (match_dup 0)
18770         (match_operator 2 "binary_fp_operator"
18771            [(match_dup 0)
18772             (match_operand 3 "memory_operand" "")]))]
18773   "REGNO (operands[0]) != REGNO (operands[1])"
18774   [(set (match_dup 0) (match_dup 3))
18775    (set (match_dup 0) (match_dup 4))]
18777   ;; The % modifier is not operational anymore in peephole2's, so we have to
18778   ;; swap the operands manually in the case of addition and multiplication.
18779   "if (COMMUTATIVE_ARITH_P (operands[2]))
18780      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18781                                  operands[0], operands[1]);
18782    else
18783      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18784                                  operands[1], operands[0]);")
18786 ;; Conditional addition patterns
18787 (define_expand "addqicc"
18788   [(match_operand:QI 0 "register_operand" "")
18789    (match_operand 1 "comparison_operator" "")
18790    (match_operand:QI 2 "register_operand" "")
18791    (match_operand:QI 3 "const_int_operand" "")]
18792   ""
18793   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18795 (define_expand "addhicc"
18796   [(match_operand:HI 0 "register_operand" "")
18797    (match_operand 1 "comparison_operator" "")
18798    (match_operand:HI 2 "register_operand" "")
18799    (match_operand:HI 3 "const_int_operand" "")]
18800   ""
18801   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18803 (define_expand "addsicc"
18804   [(match_operand:SI 0 "register_operand" "")
18805    (match_operand 1 "comparison_operator" "")
18806    (match_operand:SI 2 "register_operand" "")
18807    (match_operand:SI 3 "const_int_operand" "")]
18808   ""
18809   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18811 (define_expand "adddicc"
18812   [(match_operand:DI 0 "register_operand" "")
18813    (match_operand 1 "comparison_operator" "")
18814    (match_operand:DI 2 "register_operand" "")
18815    (match_operand:DI 3 "const_int_operand" "")]
18816   "TARGET_64BIT"
18817   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18820 ;; Misc patterns (?)
18822 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18823 ;; Otherwise there will be nothing to keep
18825 ;; [(set (reg ebp) (reg esp))]
18826 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18827 ;;  (clobber (eflags)]
18828 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18830 ;; in proper program order.
18831 (define_insn "pro_epilogue_adjust_stack_1"
18832   [(set (match_operand:SI 0 "register_operand" "=r,r")
18833         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18834                  (match_operand:SI 2 "immediate_operand" "i,i")))
18835    (clobber (reg:CC FLAGS_REG))
18836    (clobber (mem:BLK (scratch)))]
18837   "!TARGET_64BIT"
18839   switch (get_attr_type (insn))
18840     {
18841     case TYPE_IMOV:
18842       return "mov{l}\t{%1, %0|%0, %1}";
18844     case TYPE_ALU:
18845       if (CONST_INT_P (operands[2])
18846           && (INTVAL (operands[2]) == 128
18847               || (INTVAL (operands[2]) < 0
18848                   && INTVAL (operands[2]) != -128)))
18849         {
18850           operands[2] = GEN_INT (-INTVAL (operands[2]));
18851           return "sub{l}\t{%2, %0|%0, %2}";
18852         }
18853       return "add{l}\t{%2, %0|%0, %2}";
18855     case TYPE_LEA:
18856       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18857       return "lea{l}\t{%a2, %0|%0, %a2}";
18859     default:
18860       gcc_unreachable ();
18861     }
18863   [(set (attr "type")
18864         (cond [(eq_attr "alternative" "0")
18865                  (const_string "alu")
18866                (match_operand:SI 2 "const0_operand" "")
18867                  (const_string "imov")
18868               ]
18869               (const_string "lea")))
18870    (set_attr "mode" "SI")])
18872 (define_insn "pro_epilogue_adjust_stack_rex64"
18873   [(set (match_operand:DI 0 "register_operand" "=r,r")
18874         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18875                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18876    (clobber (reg:CC FLAGS_REG))
18877    (clobber (mem:BLK (scratch)))]
18878   "TARGET_64BIT"
18880   switch (get_attr_type (insn))
18881     {
18882     case TYPE_IMOV:
18883       return "mov{q}\t{%1, %0|%0, %1}";
18885     case TYPE_ALU:
18886       if (CONST_INT_P (operands[2])
18887           /* Avoid overflows.  */
18888           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18889           && (INTVAL (operands[2]) == 128
18890               || (INTVAL (operands[2]) < 0
18891                   && INTVAL (operands[2]) != -128)))
18892         {
18893           operands[2] = GEN_INT (-INTVAL (operands[2]));
18894           return "sub{q}\t{%2, %0|%0, %2}";
18895         }
18896       return "add{q}\t{%2, %0|%0, %2}";
18898     case TYPE_LEA:
18899       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18900       return "lea{q}\t{%a2, %0|%0, %a2}";
18902     default:
18903       gcc_unreachable ();
18904     }
18906   [(set (attr "type")
18907         (cond [(eq_attr "alternative" "0")
18908                  (const_string "alu")
18909                (match_operand:DI 2 "const0_operand" "")
18910                  (const_string "imov")
18911               ]
18912               (const_string "lea")))
18913    (set_attr "mode" "DI")])
18915 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18916   [(set (match_operand:DI 0 "register_operand" "=r,r")
18917         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18918                  (match_operand:DI 3 "immediate_operand" "i,i")))
18919    (use (match_operand:DI 2 "register_operand" "r,r"))
18920    (clobber (reg:CC FLAGS_REG))
18921    (clobber (mem:BLK (scratch)))]
18922   "TARGET_64BIT"
18924   switch (get_attr_type (insn))
18925     {
18926     case TYPE_ALU:
18927       return "add{q}\t{%2, %0|%0, %2}";
18929     case TYPE_LEA:
18930       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18931       return "lea{q}\t{%a2, %0|%0, %a2}";
18933     default:
18934       gcc_unreachable ();
18935     }
18937   [(set_attr "type" "alu,lea")
18938    (set_attr "mode" "DI")])
18940 (define_expand "allocate_stack_worker"
18941   [(match_operand:SI 0 "register_operand" "")]
18942   "TARGET_STACK_PROBE"
18944   if (reload_completed)
18945     {
18946       if (TARGET_64BIT)
18947         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18948       else
18949         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18950     }
18951   else
18952     {
18953       if (TARGET_64BIT)
18954         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18955       else
18956         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18957     }
18958   DONE;
18961 (define_insn "allocate_stack_worker_1"
18962   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18963     UNSPECV_STACK_PROBE)
18964    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18965    (clobber (match_scratch:SI 1 "=0"))
18966    (clobber (reg:CC FLAGS_REG))]
18967   "!TARGET_64BIT && TARGET_STACK_PROBE"
18968   "call\t__alloca"
18969   [(set_attr "type" "multi")
18970    (set_attr "length" "5")])
18972 (define_expand "allocate_stack_worker_postreload"
18973   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18974                                     UNSPECV_STACK_PROBE)
18975               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18976               (clobber (match_dup 0))
18977               (clobber (reg:CC FLAGS_REG))])]
18978   ""
18979   "")
18981 (define_insn "allocate_stack_worker_rex64"
18982   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18983     UNSPECV_STACK_PROBE)
18984    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18985    (clobber (match_scratch:DI 1 "=0"))
18986    (clobber (reg:CC FLAGS_REG))]
18987   "TARGET_64BIT && TARGET_STACK_PROBE"
18988   "call\t__alloca"
18989   [(set_attr "type" "multi")
18990    (set_attr "length" "5")])
18992 (define_expand "allocate_stack_worker_rex64_postreload"
18993   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18994                                     UNSPECV_STACK_PROBE)
18995               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18996               (clobber (match_dup 0))
18997               (clobber (reg:CC FLAGS_REG))])]
18998   ""
18999   "")
19001 (define_expand "allocate_stack"
19002   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19003                    (minus:SI (reg:SI SP_REG)
19004                              (match_operand:SI 1 "general_operand" "")))
19005               (clobber (reg:CC FLAGS_REG))])
19006    (parallel [(set (reg:SI SP_REG)
19007                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19008               (clobber (reg:CC FLAGS_REG))])]
19009   "TARGET_STACK_PROBE"
19011 #ifdef CHECK_STACK_LIMIT
19012   if (CONST_INT_P (operands[1])
19013       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19014     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19015                            operands[1]));
19016   else
19017 #endif
19018     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19019                                                             operands[1])));
19021   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19022   DONE;
19025 (define_expand "builtin_setjmp_receiver"
19026   [(label_ref (match_operand 0 "" ""))]
19027   "!TARGET_64BIT && flag_pic"
19029   if (TARGET_MACHO)
19030     {
19031       rtx xops[3];
19032       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19033       rtx label_rtx = gen_label_rtx ();
19034       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19035       xops[0] = xops[1] = picreg;
19036       xops[2] = gen_rtx_CONST (SImode,
19037                   gen_rtx_MINUS (SImode,
19038                     gen_rtx_LABEL_REF (SImode, label_rtx),
19039                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19040       ix86_expand_binary_operator (MINUS, SImode, xops);
19041     }
19042   else
19043     emit_insn (gen_set_got (pic_offset_table_rtx));
19044   DONE;
19047 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19049 (define_split
19050   [(set (match_operand 0 "register_operand" "")
19051         (match_operator 3 "promotable_binary_operator"
19052            [(match_operand 1 "register_operand" "")
19053             (match_operand 2 "aligned_operand" "")]))
19054    (clobber (reg:CC FLAGS_REG))]
19055   "! TARGET_PARTIAL_REG_STALL && reload_completed
19056    && ((GET_MODE (operands[0]) == HImode
19057         && ((!optimize_size && !TARGET_FAST_PREFIX)
19058             /* ??? next two lines just !satisfies_constraint_K (...) */
19059             || !CONST_INT_P (operands[2])
19060             || satisfies_constraint_K (operands[2])))
19061        || (GET_MODE (operands[0]) == QImode
19062            && (TARGET_PROMOTE_QImode || optimize_size)))"
19063   [(parallel [(set (match_dup 0)
19064                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19065               (clobber (reg:CC FLAGS_REG))])]
19066   "operands[0] = gen_lowpart (SImode, operands[0]);
19067    operands[1] = gen_lowpart (SImode, operands[1]);
19068    if (GET_CODE (operands[3]) != ASHIFT)
19069      operands[2] = gen_lowpart (SImode, operands[2]);
19070    PUT_MODE (operands[3], SImode);")
19072 ; Promote the QImode tests, as i386 has encoding of the AND
19073 ; instruction with 32-bit sign-extended immediate and thus the
19074 ; instruction size is unchanged, except in the %eax case for
19075 ; which it is increased by one byte, hence the ! optimize_size.
19076 (define_split
19077   [(set (match_operand 0 "flags_reg_operand" "")
19078         (match_operator 2 "compare_operator"
19079           [(and (match_operand 3 "aligned_operand" "")
19080                 (match_operand 4 "const_int_operand" ""))
19081            (const_int 0)]))
19082    (set (match_operand 1 "register_operand" "")
19083         (and (match_dup 3) (match_dup 4)))]
19084   "! TARGET_PARTIAL_REG_STALL && reload_completed
19085    /* Ensure that the operand will remain sign-extended immediate.  */
19086    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19087    && ! optimize_size
19088    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19089        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19090   [(parallel [(set (match_dup 0)
19091                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19092                                     (const_int 0)]))
19093               (set (match_dup 1)
19094                    (and:SI (match_dup 3) (match_dup 4)))])]
19096   operands[4]
19097     = gen_int_mode (INTVAL (operands[4])
19098                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19099   operands[1] = gen_lowpart (SImode, operands[1]);
19100   operands[3] = gen_lowpart (SImode, operands[3]);
19103 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19104 ; the TEST instruction with 32-bit sign-extended immediate and thus
19105 ; the instruction size would at least double, which is not what we
19106 ; want even with ! optimize_size.
19107 (define_split
19108   [(set (match_operand 0 "flags_reg_operand" "")
19109         (match_operator 1 "compare_operator"
19110           [(and (match_operand:HI 2 "aligned_operand" "")
19111                 (match_operand:HI 3 "const_int_operand" ""))
19112            (const_int 0)]))]
19113   "! TARGET_PARTIAL_REG_STALL && reload_completed
19114    /* Ensure that the operand will remain sign-extended immediate.  */
19115    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19116    && ! TARGET_FAST_PREFIX
19117    && ! optimize_size"
19118   [(set (match_dup 0)
19119         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19120                          (const_int 0)]))]
19122   operands[3]
19123     = gen_int_mode (INTVAL (operands[3])
19124                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19125   operands[2] = gen_lowpart (SImode, operands[2]);
19128 (define_split
19129   [(set (match_operand 0 "register_operand" "")
19130         (neg (match_operand 1 "register_operand" "")))
19131    (clobber (reg:CC FLAGS_REG))]
19132   "! TARGET_PARTIAL_REG_STALL && reload_completed
19133    && (GET_MODE (operands[0]) == HImode
19134        || (GET_MODE (operands[0]) == QImode
19135            && (TARGET_PROMOTE_QImode || optimize_size)))"
19136   [(parallel [(set (match_dup 0)
19137                    (neg:SI (match_dup 1)))
19138               (clobber (reg:CC FLAGS_REG))])]
19139   "operands[0] = gen_lowpart (SImode, operands[0]);
19140    operands[1] = gen_lowpart (SImode, operands[1]);")
19142 (define_split
19143   [(set (match_operand 0 "register_operand" "")
19144         (not (match_operand 1 "register_operand" "")))]
19145   "! TARGET_PARTIAL_REG_STALL && reload_completed
19146    && (GET_MODE (operands[0]) == HImode
19147        || (GET_MODE (operands[0]) == QImode
19148            && (TARGET_PROMOTE_QImode || optimize_size)))"
19149   [(set (match_dup 0)
19150         (not:SI (match_dup 1)))]
19151   "operands[0] = gen_lowpart (SImode, operands[0]);
19152    operands[1] = gen_lowpart (SImode, operands[1]);")
19154 (define_split
19155   [(set (match_operand 0 "register_operand" "")
19156         (if_then_else (match_operator 1 "comparison_operator"
19157                                 [(reg FLAGS_REG) (const_int 0)])
19158                       (match_operand 2 "register_operand" "")
19159                       (match_operand 3 "register_operand" "")))]
19160   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19161    && (GET_MODE (operands[0]) == HImode
19162        || (GET_MODE (operands[0]) == QImode
19163            && (TARGET_PROMOTE_QImode || optimize_size)))"
19164   [(set (match_dup 0)
19165         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19166   "operands[0] = gen_lowpart (SImode, operands[0]);
19167    operands[2] = gen_lowpart (SImode, operands[2]);
19168    operands[3] = gen_lowpart (SImode, operands[3]);")
19171 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19172 ;; transform a complex memory operation into two memory to register operations.
19174 ;; Don't push memory operands
19175 (define_peephole2
19176   [(set (match_operand:SI 0 "push_operand" "")
19177         (match_operand:SI 1 "memory_operand" ""))
19178    (match_scratch:SI 2 "r")]
19179   "!optimize_size && !TARGET_PUSH_MEMORY
19180    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19181   [(set (match_dup 2) (match_dup 1))
19182    (set (match_dup 0) (match_dup 2))]
19183   "")
19185 (define_peephole2
19186   [(set (match_operand:DI 0 "push_operand" "")
19187         (match_operand:DI 1 "memory_operand" ""))
19188    (match_scratch:DI 2 "r")]
19189   "!optimize_size && !TARGET_PUSH_MEMORY
19190    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19191   [(set (match_dup 2) (match_dup 1))
19192    (set (match_dup 0) (match_dup 2))]
19193   "")
19195 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19196 ;; SImode pushes.
19197 (define_peephole2
19198   [(set (match_operand:SF 0 "push_operand" "")
19199         (match_operand:SF 1 "memory_operand" ""))
19200    (match_scratch:SF 2 "r")]
19201   "!optimize_size && !TARGET_PUSH_MEMORY
19202    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19203   [(set (match_dup 2) (match_dup 1))
19204    (set (match_dup 0) (match_dup 2))]
19205   "")
19207 (define_peephole2
19208   [(set (match_operand:HI 0 "push_operand" "")
19209         (match_operand:HI 1 "memory_operand" ""))
19210    (match_scratch:HI 2 "r")]
19211   "!optimize_size && !TARGET_PUSH_MEMORY
19212    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19213   [(set (match_dup 2) (match_dup 1))
19214    (set (match_dup 0) (match_dup 2))]
19215   "")
19217 (define_peephole2
19218   [(set (match_operand:QI 0 "push_operand" "")
19219         (match_operand:QI 1 "memory_operand" ""))
19220    (match_scratch:QI 2 "q")]
19221   "!optimize_size && !TARGET_PUSH_MEMORY
19222    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19223   [(set (match_dup 2) (match_dup 1))
19224    (set (match_dup 0) (match_dup 2))]
19225   "")
19227 ;; Don't move an immediate directly to memory when the instruction
19228 ;; gets too big.
19229 (define_peephole2
19230   [(match_scratch:SI 1 "r")
19231    (set (match_operand:SI 0 "memory_operand" "")
19232         (const_int 0))]
19233   "! optimize_size
19234    && ! TARGET_USE_MOV0
19235    && TARGET_SPLIT_LONG_MOVES
19236    && get_attr_length (insn) >= ix86_cost->large_insn
19237    && peep2_regno_dead_p (0, FLAGS_REG)"
19238   [(parallel [(set (match_dup 1) (const_int 0))
19239               (clobber (reg:CC FLAGS_REG))])
19240    (set (match_dup 0) (match_dup 1))]
19241   "")
19243 (define_peephole2
19244   [(match_scratch:HI 1 "r")
19245    (set (match_operand:HI 0 "memory_operand" "")
19246         (const_int 0))]
19247   "! optimize_size
19248    && ! TARGET_USE_MOV0
19249    && TARGET_SPLIT_LONG_MOVES
19250    && get_attr_length (insn) >= ix86_cost->large_insn
19251    && peep2_regno_dead_p (0, FLAGS_REG)"
19252   [(parallel [(set (match_dup 2) (const_int 0))
19253               (clobber (reg:CC FLAGS_REG))])
19254    (set (match_dup 0) (match_dup 1))]
19255   "operands[2] = gen_lowpart (SImode, operands[1]);")
19257 (define_peephole2
19258   [(match_scratch:QI 1 "q")
19259    (set (match_operand:QI 0 "memory_operand" "")
19260         (const_int 0))]
19261   "! optimize_size
19262    && ! TARGET_USE_MOV0
19263    && TARGET_SPLIT_LONG_MOVES
19264    && get_attr_length (insn) >= ix86_cost->large_insn
19265    && peep2_regno_dead_p (0, FLAGS_REG)"
19266   [(parallel [(set (match_dup 2) (const_int 0))
19267               (clobber (reg:CC FLAGS_REG))])
19268    (set (match_dup 0) (match_dup 1))]
19269   "operands[2] = gen_lowpart (SImode, operands[1]);")
19271 (define_peephole2
19272   [(match_scratch:SI 2 "r")
19273    (set (match_operand:SI 0 "memory_operand" "")
19274         (match_operand:SI 1 "immediate_operand" ""))]
19275   "! optimize_size
19276    && get_attr_length (insn) >= ix86_cost->large_insn
19277    && TARGET_SPLIT_LONG_MOVES"
19278   [(set (match_dup 2) (match_dup 1))
19279    (set (match_dup 0) (match_dup 2))]
19280   "")
19282 (define_peephole2
19283   [(match_scratch:HI 2 "r")
19284    (set (match_operand:HI 0 "memory_operand" "")
19285         (match_operand:HI 1 "immediate_operand" ""))]
19286   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19287   && TARGET_SPLIT_LONG_MOVES"
19288   [(set (match_dup 2) (match_dup 1))
19289    (set (match_dup 0) (match_dup 2))]
19290   "")
19292 (define_peephole2
19293   [(match_scratch:QI 2 "q")
19294    (set (match_operand:QI 0 "memory_operand" "")
19295         (match_operand:QI 1 "immediate_operand" ""))]
19296   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19297   && TARGET_SPLIT_LONG_MOVES"
19298   [(set (match_dup 2) (match_dup 1))
19299    (set (match_dup 0) (match_dup 2))]
19300   "")
19302 ;; Don't compare memory with zero, load and use a test instead.
19303 (define_peephole2
19304   [(set (match_operand 0 "flags_reg_operand" "")
19305         (match_operator 1 "compare_operator"
19306           [(match_operand:SI 2 "memory_operand" "")
19307            (const_int 0)]))
19308    (match_scratch:SI 3 "r")]
19309   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19310   [(set (match_dup 3) (match_dup 2))
19311    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19312   "")
19314 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19315 ;; Don't split NOTs with a displacement operand, because resulting XOR
19316 ;; will not be pairable anyway.
19318 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19319 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19320 ;; so this split helps here as well.
19322 ;; Note: Can't do this as a regular split because we can't get proper
19323 ;; lifetime information then.
19325 (define_peephole2
19326   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19327         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19328   "!optimize_size
19329    && peep2_regno_dead_p (0, FLAGS_REG)
19330    && ((TARGET_PENTIUM
19331         && (!MEM_P (operands[0])
19332             || !memory_displacement_operand (operands[0], SImode)))
19333        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19334   [(parallel [(set (match_dup 0)
19335                    (xor:SI (match_dup 1) (const_int -1)))
19336               (clobber (reg:CC FLAGS_REG))])]
19337   "")
19339 (define_peephole2
19340   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19341         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19342   "!optimize_size
19343    && peep2_regno_dead_p (0, FLAGS_REG)
19344    && ((TARGET_PENTIUM
19345         && (!MEM_P (operands[0])
19346             || !memory_displacement_operand (operands[0], HImode)))
19347        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19348   [(parallel [(set (match_dup 0)
19349                    (xor:HI (match_dup 1) (const_int -1)))
19350               (clobber (reg:CC FLAGS_REG))])]
19351   "")
19353 (define_peephole2
19354   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19355         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19356   "!optimize_size
19357    && peep2_regno_dead_p (0, FLAGS_REG)
19358    && ((TARGET_PENTIUM
19359         && (!MEM_P (operands[0])
19360             || !memory_displacement_operand (operands[0], QImode)))
19361        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19362   [(parallel [(set (match_dup 0)
19363                    (xor:QI (match_dup 1) (const_int -1)))
19364               (clobber (reg:CC FLAGS_REG))])]
19365   "")
19367 ;; Non pairable "test imm, reg" instructions can be translated to
19368 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19369 ;; byte opcode instead of two, have a short form for byte operands),
19370 ;; so do it for other CPUs as well.  Given that the value was dead,
19371 ;; this should not create any new dependencies.  Pass on the sub-word
19372 ;; versions if we're concerned about partial register stalls.
19374 (define_peephole2
19375   [(set (match_operand 0 "flags_reg_operand" "")
19376         (match_operator 1 "compare_operator"
19377           [(and:SI (match_operand:SI 2 "register_operand" "")
19378                    (match_operand:SI 3 "immediate_operand" ""))
19379            (const_int 0)]))]
19380   "ix86_match_ccmode (insn, CCNOmode)
19381    && (true_regnum (operands[2]) != 0
19382        || satisfies_constraint_K (operands[3]))
19383    && peep2_reg_dead_p (1, operands[2])"
19384   [(parallel
19385      [(set (match_dup 0)
19386            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19387                             (const_int 0)]))
19388       (set (match_dup 2)
19389            (and:SI (match_dup 2) (match_dup 3)))])]
19390   "")
19392 ;; We don't need to handle HImode case, because it will be promoted to SImode
19393 ;; on ! TARGET_PARTIAL_REG_STALL
19395 (define_peephole2
19396   [(set (match_operand 0 "flags_reg_operand" "")
19397         (match_operator 1 "compare_operator"
19398           [(and:QI (match_operand:QI 2 "register_operand" "")
19399                    (match_operand:QI 3 "immediate_operand" ""))
19400            (const_int 0)]))]
19401   "! TARGET_PARTIAL_REG_STALL
19402    && ix86_match_ccmode (insn, CCNOmode)
19403    && true_regnum (operands[2]) != 0
19404    && peep2_reg_dead_p (1, operands[2])"
19405   [(parallel
19406      [(set (match_dup 0)
19407            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19408                             (const_int 0)]))
19409       (set (match_dup 2)
19410            (and:QI (match_dup 2) (match_dup 3)))])]
19411   "")
19413 (define_peephole2
19414   [(set (match_operand 0 "flags_reg_operand" "")
19415         (match_operator 1 "compare_operator"
19416           [(and:SI
19417              (zero_extract:SI
19418                (match_operand 2 "ext_register_operand" "")
19419                (const_int 8)
19420                (const_int 8))
19421              (match_operand 3 "const_int_operand" ""))
19422            (const_int 0)]))]
19423   "! TARGET_PARTIAL_REG_STALL
19424    && ix86_match_ccmode (insn, CCNOmode)
19425    && true_regnum (operands[2]) != 0
19426    && peep2_reg_dead_p (1, operands[2])"
19427   [(parallel [(set (match_dup 0)
19428                    (match_op_dup 1
19429                      [(and:SI
19430                         (zero_extract:SI
19431                           (match_dup 2)
19432                           (const_int 8)
19433                           (const_int 8))
19434                         (match_dup 3))
19435                       (const_int 0)]))
19436               (set (zero_extract:SI (match_dup 2)
19437                                     (const_int 8)
19438                                     (const_int 8))
19439                    (and:SI
19440                      (zero_extract:SI
19441                        (match_dup 2)
19442                        (const_int 8)
19443                        (const_int 8))
19444                      (match_dup 3)))])]
19445   "")
19447 ;; Don't do logical operations with memory inputs.
19448 (define_peephole2
19449   [(match_scratch:SI 2 "r")
19450    (parallel [(set (match_operand:SI 0 "register_operand" "")
19451                    (match_operator:SI 3 "arith_or_logical_operator"
19452                      [(match_dup 0)
19453                       (match_operand:SI 1 "memory_operand" "")]))
19454               (clobber (reg:CC FLAGS_REG))])]
19455   "! optimize_size && ! TARGET_READ_MODIFY"
19456   [(set (match_dup 2) (match_dup 1))
19457    (parallel [(set (match_dup 0)
19458                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19459               (clobber (reg:CC FLAGS_REG))])]
19460   "")
19462 (define_peephole2
19463   [(match_scratch:SI 2 "r")
19464    (parallel [(set (match_operand:SI 0 "register_operand" "")
19465                    (match_operator:SI 3 "arith_or_logical_operator"
19466                      [(match_operand:SI 1 "memory_operand" "")
19467                       (match_dup 0)]))
19468               (clobber (reg:CC FLAGS_REG))])]
19469   "! optimize_size && ! TARGET_READ_MODIFY"
19470   [(set (match_dup 2) (match_dup 1))
19471    (parallel [(set (match_dup 0)
19472                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19473               (clobber (reg:CC FLAGS_REG))])]
19474   "")
19476 ; Don't do logical operations with memory outputs
19478 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19479 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19480 ; the same decoder scheduling characteristics as the original.
19482 (define_peephole2
19483   [(match_scratch:SI 2 "r")
19484    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19485                    (match_operator:SI 3 "arith_or_logical_operator"
19486                      [(match_dup 0)
19487                       (match_operand:SI 1 "nonmemory_operand" "")]))
19488               (clobber (reg:CC FLAGS_REG))])]
19489   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19490   [(set (match_dup 2) (match_dup 0))
19491    (parallel [(set (match_dup 2)
19492                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19493               (clobber (reg:CC FLAGS_REG))])
19494    (set (match_dup 0) (match_dup 2))]
19495   "")
19497 (define_peephole2
19498   [(match_scratch:SI 2 "r")
19499    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19500                    (match_operator:SI 3 "arith_or_logical_operator"
19501                      [(match_operand:SI 1 "nonmemory_operand" "")
19502                       (match_dup 0)]))
19503               (clobber (reg:CC FLAGS_REG))])]
19504   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19505   [(set (match_dup 2) (match_dup 0))
19506    (parallel [(set (match_dup 2)
19507                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19508               (clobber (reg:CC FLAGS_REG))])
19509    (set (match_dup 0) (match_dup 2))]
19510   "")
19512 ;; Attempt to always use XOR for zeroing registers.
19513 (define_peephole2
19514   [(set (match_operand 0 "register_operand" "")
19515         (match_operand 1 "const0_operand" ""))]
19516   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19517    && (! TARGET_USE_MOV0 || optimize_size)
19518    && GENERAL_REG_P (operands[0])
19519    && peep2_regno_dead_p (0, FLAGS_REG)"
19520   [(parallel [(set (match_dup 0) (const_int 0))
19521               (clobber (reg:CC FLAGS_REG))])]
19523   operands[0] = gen_lowpart (word_mode, operands[0]);
19526 (define_peephole2
19527   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19528         (const_int 0))]
19529   "(GET_MODE (operands[0]) == QImode
19530     || GET_MODE (operands[0]) == HImode)
19531    && (! TARGET_USE_MOV0 || optimize_size)
19532    && peep2_regno_dead_p (0, FLAGS_REG)"
19533   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19534               (clobber (reg:CC FLAGS_REG))])])
19536 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19537 (define_peephole2
19538   [(set (match_operand 0 "register_operand" "")
19539         (const_int -1))]
19540   "(GET_MODE (operands[0]) == HImode
19541     || GET_MODE (operands[0]) == SImode
19542     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19543    && (optimize_size || TARGET_PENTIUM)
19544    && peep2_regno_dead_p (0, FLAGS_REG)"
19545   [(parallel [(set (match_dup 0) (const_int -1))
19546               (clobber (reg:CC FLAGS_REG))])]
19547   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19548                               operands[0]);")
19550 ;; Attempt to convert simple leas to adds. These can be created by
19551 ;; move expanders.
19552 (define_peephole2
19553   [(set (match_operand:SI 0 "register_operand" "")
19554         (plus:SI (match_dup 0)
19555                  (match_operand:SI 1 "nonmemory_operand" "")))]
19556   "peep2_regno_dead_p (0, FLAGS_REG)"
19557   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19558               (clobber (reg:CC FLAGS_REG))])]
19559   "")
19561 (define_peephole2
19562   [(set (match_operand:SI 0 "register_operand" "")
19563         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19564                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19565   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19566   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19567               (clobber (reg:CC FLAGS_REG))])]
19568   "operands[2] = gen_lowpart (SImode, operands[2]);")
19570 (define_peephole2
19571   [(set (match_operand:DI 0 "register_operand" "")
19572         (plus:DI (match_dup 0)
19573                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19574   "peep2_regno_dead_p (0, FLAGS_REG)"
19575   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19576               (clobber (reg:CC FLAGS_REG))])]
19577   "")
19579 (define_peephole2
19580   [(set (match_operand:SI 0 "register_operand" "")
19581         (mult:SI (match_dup 0)
19582                  (match_operand:SI 1 "const_int_operand" "")))]
19583   "exact_log2 (INTVAL (operands[1])) >= 0
19584    && peep2_regno_dead_p (0, FLAGS_REG)"
19585   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19586               (clobber (reg:CC FLAGS_REG))])]
19587   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19589 (define_peephole2
19590   [(set (match_operand:DI 0 "register_operand" "")
19591         (mult:DI (match_dup 0)
19592                  (match_operand:DI 1 "const_int_operand" "")))]
19593   "exact_log2 (INTVAL (operands[1])) >= 0
19594    && peep2_regno_dead_p (0, FLAGS_REG)"
19595   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19596               (clobber (reg:CC FLAGS_REG))])]
19597   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19599 (define_peephole2
19600   [(set (match_operand:SI 0 "register_operand" "")
19601         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19602                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19603   "exact_log2 (INTVAL (operands[2])) >= 0
19604    && REGNO (operands[0]) == REGNO (operands[1])
19605    && peep2_regno_dead_p (0, FLAGS_REG)"
19606   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19607               (clobber (reg:CC FLAGS_REG))])]
19608   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19610 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19611 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19612 ;; many CPUs it is also faster, since special hardware to avoid esp
19613 ;; dependencies is present.
19615 ;; While some of these conversions may be done using splitters, we use peepholes
19616 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19618 ;; Convert prologue esp subtractions to push.
19619 ;; We need register to push.  In order to keep verify_flow_info happy we have
19620 ;; two choices
19621 ;; - use scratch and clobber it in order to avoid dependencies
19622 ;; - use already live register
19623 ;; We can't use the second way right now, since there is no reliable way how to
19624 ;; verify that given register is live.  First choice will also most likely in
19625 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19626 ;; call clobbered registers are dead.  We may want to use base pointer as an
19627 ;; alternative when no register is available later.
19629 (define_peephole2
19630   [(match_scratch:SI 0 "r")
19631    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19632               (clobber (reg:CC FLAGS_REG))
19633               (clobber (mem:BLK (scratch)))])]
19634   "optimize_size || !TARGET_SUB_ESP_4"
19635   [(clobber (match_dup 0))
19636    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19637               (clobber (mem:BLK (scratch)))])])
19639 (define_peephole2
19640   [(match_scratch:SI 0 "r")
19641    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19642               (clobber (reg:CC FLAGS_REG))
19643               (clobber (mem:BLK (scratch)))])]
19644   "optimize_size || !TARGET_SUB_ESP_8"
19645   [(clobber (match_dup 0))
19646    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19647    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19648               (clobber (mem:BLK (scratch)))])])
19650 ;; Convert esp subtractions to push.
19651 (define_peephole2
19652   [(match_scratch:SI 0 "r")
19653    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19654               (clobber (reg:CC FLAGS_REG))])]
19655   "optimize_size || !TARGET_SUB_ESP_4"
19656   [(clobber (match_dup 0))
19657    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19659 (define_peephole2
19660   [(match_scratch:SI 0 "r")
19661    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19662               (clobber (reg:CC FLAGS_REG))])]
19663   "optimize_size || !TARGET_SUB_ESP_8"
19664   [(clobber (match_dup 0))
19665    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19666    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19668 ;; Convert epilogue deallocator to pop.
19669 (define_peephole2
19670   [(match_scratch:SI 0 "r")
19671    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19672               (clobber (reg:CC FLAGS_REG))
19673               (clobber (mem:BLK (scratch)))])]
19674   "optimize_size || !TARGET_ADD_ESP_4"
19675   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19676               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19677               (clobber (mem:BLK (scratch)))])]
19678   "")
19680 ;; Two pops case is tricky, since pop causes dependency on destination register.
19681 ;; We use two registers if available.
19682 (define_peephole2
19683   [(match_scratch:SI 0 "r")
19684    (match_scratch:SI 1 "r")
19685    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19686               (clobber (reg:CC FLAGS_REG))
19687               (clobber (mem:BLK (scratch)))])]
19688   "optimize_size || !TARGET_ADD_ESP_8"
19689   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19690               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19691               (clobber (mem:BLK (scratch)))])
19692    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19693               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19694   "")
19696 (define_peephole2
19697   [(match_scratch:SI 0 "r")
19698    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19699               (clobber (reg:CC FLAGS_REG))
19700               (clobber (mem:BLK (scratch)))])]
19701   "optimize_size"
19702   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19703               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19704               (clobber (mem:BLK (scratch)))])
19705    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19706               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19707   "")
19709 ;; Convert esp additions to pop.
19710 (define_peephole2
19711   [(match_scratch:SI 0 "r")
19712    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19713               (clobber (reg:CC FLAGS_REG))])]
19714   ""
19715   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19716               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19717   "")
19719 ;; Two pops case is tricky, since pop causes dependency on destination register.
19720 ;; We use two registers if available.
19721 (define_peephole2
19722   [(match_scratch:SI 0 "r")
19723    (match_scratch:SI 1 "r")
19724    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19725               (clobber (reg:CC FLAGS_REG))])]
19726   ""
19727   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19728               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19729    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19730               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19731   "")
19733 (define_peephole2
19734   [(match_scratch:SI 0 "r")
19735    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19736               (clobber (reg:CC FLAGS_REG))])]
19737   "optimize_size"
19738   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19739               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19740    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19741               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19742   "")
19744 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19745 ;; required and register dies.  Similarly for 128 to plus -128.
19746 (define_peephole2
19747   [(set (match_operand 0 "flags_reg_operand" "")
19748         (match_operator 1 "compare_operator"
19749           [(match_operand 2 "register_operand" "")
19750            (match_operand 3 "const_int_operand" "")]))]
19751   "(INTVAL (operands[3]) == -1
19752     || INTVAL (operands[3]) == 1
19753     || INTVAL (operands[3]) == 128)
19754    && ix86_match_ccmode (insn, CCGCmode)
19755    && peep2_reg_dead_p (1, operands[2])"
19756   [(parallel [(set (match_dup 0)
19757                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19758               (clobber (match_dup 2))])]
19759   "")
19761 (define_peephole2
19762   [(match_scratch:DI 0 "r")
19763    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19764               (clobber (reg:CC FLAGS_REG))
19765               (clobber (mem:BLK (scratch)))])]
19766   "optimize_size || !TARGET_SUB_ESP_4"
19767   [(clobber (match_dup 0))
19768    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19769               (clobber (mem:BLK (scratch)))])])
19771 (define_peephole2
19772   [(match_scratch:DI 0 "r")
19773    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19774               (clobber (reg:CC FLAGS_REG))
19775               (clobber (mem:BLK (scratch)))])]
19776   "optimize_size || !TARGET_SUB_ESP_8"
19777   [(clobber (match_dup 0))
19778    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19779    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19780               (clobber (mem:BLK (scratch)))])])
19782 ;; Convert esp subtractions to push.
19783 (define_peephole2
19784   [(match_scratch:DI 0 "r")
19785    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19786               (clobber (reg:CC FLAGS_REG))])]
19787   "optimize_size || !TARGET_SUB_ESP_4"
19788   [(clobber (match_dup 0))
19789    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19791 (define_peephole2
19792   [(match_scratch:DI 0 "r")
19793    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19794               (clobber (reg:CC FLAGS_REG))])]
19795   "optimize_size || !TARGET_SUB_ESP_8"
19796   [(clobber (match_dup 0))
19797    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19798    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19800 ;; Convert epilogue deallocator to pop.
19801 (define_peephole2
19802   [(match_scratch:DI 0 "r")
19803    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19804               (clobber (reg:CC FLAGS_REG))
19805               (clobber (mem:BLK (scratch)))])]
19806   "optimize_size || !TARGET_ADD_ESP_4"
19807   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19808               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19809               (clobber (mem:BLK (scratch)))])]
19810   "")
19812 ;; Two pops case is tricky, since pop causes dependency on destination register.
19813 ;; We use two registers if available.
19814 (define_peephole2
19815   [(match_scratch:DI 0 "r")
19816    (match_scratch:DI 1 "r")
19817    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19818               (clobber (reg:CC FLAGS_REG))
19819               (clobber (mem:BLK (scratch)))])]
19820   "optimize_size || !TARGET_ADD_ESP_8"
19821   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19822               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19823               (clobber (mem:BLK (scratch)))])
19824    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19825               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19826   "")
19828 (define_peephole2
19829   [(match_scratch:DI 0 "r")
19830    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19831               (clobber (reg:CC FLAGS_REG))
19832               (clobber (mem:BLK (scratch)))])]
19833   "optimize_size"
19834   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19835               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19836               (clobber (mem:BLK (scratch)))])
19837    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19838               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19839   "")
19841 ;; Convert esp additions to pop.
19842 (define_peephole2
19843   [(match_scratch:DI 0 "r")
19844    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19845               (clobber (reg:CC FLAGS_REG))])]
19846   ""
19847   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19848               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19849   "")
19851 ;; Two pops case is tricky, since pop causes dependency on destination register.
19852 ;; We use two registers if available.
19853 (define_peephole2
19854   [(match_scratch:DI 0 "r")
19855    (match_scratch:DI 1 "r")
19856    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19857               (clobber (reg:CC FLAGS_REG))])]
19858   ""
19859   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19860               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19861    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19862               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19863   "")
19865 (define_peephole2
19866   [(match_scratch:DI 0 "r")
19867    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19868               (clobber (reg:CC FLAGS_REG))])]
19869   "optimize_size"
19870   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19871               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19872    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19873               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19874   "")
19876 ;; Convert imul by three, five and nine into lea
19877 (define_peephole2
19878   [(parallel
19879     [(set (match_operand:SI 0 "register_operand" "")
19880           (mult:SI (match_operand:SI 1 "register_operand" "")
19881                    (match_operand:SI 2 "const_int_operand" "")))
19882      (clobber (reg:CC FLAGS_REG))])]
19883   "INTVAL (operands[2]) == 3
19884    || INTVAL (operands[2]) == 5
19885    || INTVAL (operands[2]) == 9"
19886   [(set (match_dup 0)
19887         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19888                  (match_dup 1)))]
19889   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19891 (define_peephole2
19892   [(parallel
19893     [(set (match_operand:SI 0 "register_operand" "")
19894           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19895                    (match_operand:SI 2 "const_int_operand" "")))
19896      (clobber (reg:CC FLAGS_REG))])]
19897   "!optimize_size
19898    && (INTVAL (operands[2]) == 3
19899        || INTVAL (operands[2]) == 5
19900        || INTVAL (operands[2]) == 9)"
19901   [(set (match_dup 0) (match_dup 1))
19902    (set (match_dup 0)
19903         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19904                  (match_dup 0)))]
19905   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19907 (define_peephole2
19908   [(parallel
19909     [(set (match_operand:DI 0 "register_operand" "")
19910           (mult:DI (match_operand:DI 1 "register_operand" "")
19911                    (match_operand:DI 2 "const_int_operand" "")))
19912      (clobber (reg:CC FLAGS_REG))])]
19913   "TARGET_64BIT
19914    && (INTVAL (operands[2]) == 3
19915        || INTVAL (operands[2]) == 5
19916        || INTVAL (operands[2]) == 9)"
19917   [(set (match_dup 0)
19918         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19919                  (match_dup 1)))]
19920   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19922 (define_peephole2
19923   [(parallel
19924     [(set (match_operand:DI 0 "register_operand" "")
19925           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19926                    (match_operand:DI 2 "const_int_operand" "")))
19927      (clobber (reg:CC FLAGS_REG))])]
19928   "TARGET_64BIT
19929    && !optimize_size
19930    && (INTVAL (operands[2]) == 3
19931        || INTVAL (operands[2]) == 5
19932        || INTVAL (operands[2]) == 9)"
19933   [(set (match_dup 0) (match_dup 1))
19934    (set (match_dup 0)
19935         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19936                  (match_dup 0)))]
19937   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19939 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19940 ;; imul $32bit_imm, reg, reg is direct decoded.
19941 (define_peephole2
19942   [(match_scratch:DI 3 "r")
19943    (parallel [(set (match_operand:DI 0 "register_operand" "")
19944                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19945                             (match_operand:DI 2 "immediate_operand" "")))
19946               (clobber (reg:CC FLAGS_REG))])]
19947   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19948    && !satisfies_constraint_K (operands[2])"
19949   [(set (match_dup 3) (match_dup 1))
19950    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19951               (clobber (reg:CC FLAGS_REG))])]
19954 (define_peephole2
19955   [(match_scratch:SI 3 "r")
19956    (parallel [(set (match_operand:SI 0 "register_operand" "")
19957                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19958                             (match_operand:SI 2 "immediate_operand" "")))
19959               (clobber (reg:CC FLAGS_REG))])]
19960   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19961    && !satisfies_constraint_K (operands[2])"
19962   [(set (match_dup 3) (match_dup 1))
19963    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19964               (clobber (reg:CC FLAGS_REG))])]
19967 (define_peephole2
19968   [(match_scratch:SI 3 "r")
19969    (parallel [(set (match_operand:DI 0 "register_operand" "")
19970                    (zero_extend:DI
19971                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19972                               (match_operand:SI 2 "immediate_operand" ""))))
19973               (clobber (reg:CC FLAGS_REG))])]
19974   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19975    && !satisfies_constraint_K (operands[2])"
19976   [(set (match_dup 3) (match_dup 1))
19977    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19978               (clobber (reg:CC FLAGS_REG))])]
19981 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19982 ;; Convert it into imul reg, reg
19983 ;; It would be better to force assembler to encode instruction using long
19984 ;; immediate, but there is apparently no way to do so.
19985 (define_peephole2
19986   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19987                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19988                             (match_operand:DI 2 "const_int_operand" "")))
19989               (clobber (reg:CC FLAGS_REG))])
19990    (match_scratch:DI 3 "r")]
19991   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19992    && satisfies_constraint_K (operands[2])"
19993   [(set (match_dup 3) (match_dup 2))
19994    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19995               (clobber (reg:CC FLAGS_REG))])]
19997   if (!rtx_equal_p (operands[0], operands[1]))
19998     emit_move_insn (operands[0], operands[1]);
20001 (define_peephole2
20002   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20003                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20004                             (match_operand:SI 2 "const_int_operand" "")))
20005               (clobber (reg:CC FLAGS_REG))])
20006    (match_scratch:SI 3 "r")]
20007   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20008    && satisfies_constraint_K (operands[2])"
20009   [(set (match_dup 3) (match_dup 2))
20010    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20011               (clobber (reg:CC FLAGS_REG))])]
20013   if (!rtx_equal_p (operands[0], operands[1]))
20014     emit_move_insn (operands[0], operands[1]);
20017 (define_peephole2
20018   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20019                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20020                             (match_operand:HI 2 "immediate_operand" "")))
20021               (clobber (reg:CC FLAGS_REG))])
20022    (match_scratch:HI 3 "r")]
20023   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20024   [(set (match_dup 3) (match_dup 2))
20025    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20026               (clobber (reg:CC FLAGS_REG))])]
20028   if (!rtx_equal_p (operands[0], operands[1]))
20029     emit_move_insn (operands[0], operands[1]);
20032 ;; After splitting up read-modify operations, array accesses with memory
20033 ;; operands might end up in form:
20034 ;;  sall    $2, %eax
20035 ;;  movl    4(%esp), %edx
20036 ;;  addl    %edx, %eax
20037 ;; instead of pre-splitting:
20038 ;;  sall    $2, %eax
20039 ;;  addl    4(%esp), %eax
20040 ;; Turn it into:
20041 ;;  movl    4(%esp), %edx
20042 ;;  leal    (%edx,%eax,4), %eax
20044 (define_peephole2
20045   [(parallel [(set (match_operand 0 "register_operand" "")
20046                    (ashift (match_operand 1 "register_operand" "")
20047                            (match_operand 2 "const_int_operand" "")))
20048                (clobber (reg:CC FLAGS_REG))])
20049    (set (match_operand 3 "register_operand")
20050         (match_operand 4 "x86_64_general_operand" ""))
20051    (parallel [(set (match_operand 5 "register_operand" "")
20052                    (plus (match_operand 6 "register_operand" "")
20053                          (match_operand 7 "register_operand" "")))
20054                    (clobber (reg:CC FLAGS_REG))])]
20055   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20056    /* Validate MODE for lea.  */
20057    && ((!TARGET_PARTIAL_REG_STALL
20058         && (GET_MODE (operands[0]) == QImode
20059             || GET_MODE (operands[0]) == HImode))
20060        || GET_MODE (operands[0]) == SImode
20061        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20062    /* We reorder load and the shift.  */
20063    && !rtx_equal_p (operands[1], operands[3])
20064    && !reg_overlap_mentioned_p (operands[0], operands[4])
20065    /* Last PLUS must consist of operand 0 and 3.  */
20066    && !rtx_equal_p (operands[0], operands[3])
20067    && (rtx_equal_p (operands[3], operands[6])
20068        || rtx_equal_p (operands[3], operands[7]))
20069    && (rtx_equal_p (operands[0], operands[6])
20070        || rtx_equal_p (operands[0], operands[7]))
20071    /* The intermediate operand 0 must die or be same as output.  */
20072    && (rtx_equal_p (operands[0], operands[5])
20073        || peep2_reg_dead_p (3, operands[0]))"
20074   [(set (match_dup 3) (match_dup 4))
20075    (set (match_dup 0) (match_dup 1))]
20077   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20078   int scale = 1 << INTVAL (operands[2]);
20079   rtx index = gen_lowpart (Pmode, operands[1]);
20080   rtx base = gen_lowpart (Pmode, operands[3]);
20081   rtx dest = gen_lowpart (mode, operands[5]);
20083   operands[1] = gen_rtx_PLUS (Pmode, base,
20084                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20085   if (mode != Pmode)
20086     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20087   operands[0] = dest;
20090 ;; Call-value patterns last so that the wildcard operand does not
20091 ;; disrupt insn-recog's switch tables.
20093 (define_insn "*call_value_pop_0"
20094   [(set (match_operand 0 "" "")
20095         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20096               (match_operand:SI 2 "" "")))
20097    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20098                             (match_operand:SI 3 "immediate_operand" "")))]
20099   "!TARGET_64BIT"
20101   if (SIBLING_CALL_P (insn))
20102     return "jmp\t%P1";
20103   else
20104     return "call\t%P1";
20106   [(set_attr "type" "callv")])
20108 (define_insn "*call_value_pop_1"
20109   [(set (match_operand 0 "" "")
20110         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20111               (match_operand:SI 2 "" "")))
20112    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20113                             (match_operand:SI 3 "immediate_operand" "i")))]
20114   "!TARGET_64BIT"
20116   if (constant_call_address_operand (operands[1], Pmode))
20117     {
20118       if (SIBLING_CALL_P (insn))
20119         return "jmp\t%P1";
20120       else
20121         return "call\t%P1";
20122     }
20123   if (SIBLING_CALL_P (insn))
20124     return "jmp\t%A1";
20125   else
20126     return "call\t%A1";
20128   [(set_attr "type" "callv")])
20130 (define_insn "*call_value_0"
20131   [(set (match_operand 0 "" "")
20132         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20133               (match_operand:SI 2 "" "")))]
20134   "!TARGET_64BIT"
20136   if (SIBLING_CALL_P (insn))
20137     return "jmp\t%P1";
20138   else
20139     return "call\t%P1";
20141   [(set_attr "type" "callv")])
20143 (define_insn "*call_value_0_rex64"
20144   [(set (match_operand 0 "" "")
20145         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20146               (match_operand:DI 2 "const_int_operand" "")))]
20147   "TARGET_64BIT"
20149   if (SIBLING_CALL_P (insn))
20150     return "jmp\t%P1";
20151   else
20152     return "call\t%P1";
20154   [(set_attr "type" "callv")])
20156 (define_insn "*call_value_1"
20157   [(set (match_operand 0 "" "")
20158         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20159               (match_operand:SI 2 "" "")))]
20160   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20162   if (constant_call_address_operand (operands[1], Pmode))
20163     return "call\t%P1";
20164   return "call\t%A1";
20166   [(set_attr "type" "callv")])
20168 (define_insn "*sibcall_value_1"
20169   [(set (match_operand 0 "" "")
20170         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20171               (match_operand:SI 2 "" "")))]
20172   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20174   if (constant_call_address_operand (operands[1], Pmode))
20175     return "jmp\t%P1";
20176   return "jmp\t%A1";
20178   [(set_attr "type" "callv")])
20180 (define_insn "*call_value_1_rex64"
20181   [(set (match_operand 0 "" "")
20182         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20183               (match_operand:DI 2 "" "")))]
20184   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20186   if (constant_call_address_operand (operands[1], Pmode))
20187     return "call\t%P1";
20188   return "call\t%A1";
20190   [(set_attr "type" "callv")])
20192 (define_insn "*sibcall_value_1_rex64"
20193   [(set (match_operand 0 "" "")
20194         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20195               (match_operand:DI 2 "" "")))]
20196   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20197   "jmp\t%P1"
20198   [(set_attr "type" "callv")])
20200 (define_insn "*sibcall_value_1_rex64_v"
20201   [(set (match_operand 0 "" "")
20202         (call (mem:QI (reg:DI R11_REG))
20203               (match_operand:DI 1 "" "")))]
20204   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20205   "jmp\t*%%r11"
20206   [(set_attr "type" "callv")])
20208 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20209 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20210 ;; caught for use by garbage collectors and the like.  Using an insn that
20211 ;; maps to SIGILL makes it more likely the program will rightfully die.
20212 ;; Keeping with tradition, "6" is in honor of #UD.
20213 (define_insn "trap"
20214   [(trap_if (const_int 1) (const_int 6))]
20215   ""
20216   { return ASM_SHORT "0x0b0f"; }
20217   [(set_attr "length" "2")])
20219 (define_expand "sse_prologue_save"
20220   [(parallel [(set (match_operand:BLK 0 "" "")
20221                    (unspec:BLK [(reg:DI 21)
20222                                 (reg:DI 22)
20223                                 (reg:DI 23)
20224                                 (reg:DI 24)
20225                                 (reg:DI 25)
20226                                 (reg:DI 26)
20227                                 (reg:DI 27)
20228                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20229               (use (match_operand:DI 1 "register_operand" ""))
20230               (use (match_operand:DI 2 "immediate_operand" ""))
20231               (use (label_ref:DI (match_operand 3 "" "")))])]
20232   "TARGET_64BIT"
20233   "")
20235 (define_insn "*sse_prologue_save_insn"
20236   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20237                           (match_operand:DI 4 "const_int_operand" "n")))
20238         (unspec:BLK [(reg:DI 21)
20239                      (reg:DI 22)
20240                      (reg:DI 23)
20241                      (reg:DI 24)
20242                      (reg:DI 25)
20243                      (reg:DI 26)
20244                      (reg:DI 27)
20245                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20246    (use (match_operand:DI 1 "register_operand" "r"))
20247    (use (match_operand:DI 2 "const_int_operand" "i"))
20248    (use (label_ref:DI (match_operand 3 "" "X")))]
20249   "TARGET_64BIT
20250    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20251    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20252   "*
20254   int i;
20255   operands[0] = gen_rtx_MEM (Pmode,
20256                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20257   output_asm_insn (\"jmp\\t%A1\", operands);
20258   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20259     {
20260       operands[4] = adjust_address (operands[0], DImode, i*16);
20261       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20262       PUT_MODE (operands[4], TImode);
20263       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20264         output_asm_insn (\"rex\", operands);
20265       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20266     }
20267   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20268                              CODE_LABEL_NUMBER (operands[3]));
20269   return \"\";
20271   "
20272   [(set_attr "type" "other")
20273    (set_attr "length_immediate" "0")
20274    (set_attr "length_address" "0")
20275    (set_attr "length" "135")
20276    (set_attr "memory" "store")
20277    (set_attr "modrm" "0")
20278    (set_attr "mode" "DI")])
20280 (define_expand "prefetch"
20281   [(prefetch (match_operand 0 "address_operand" "")
20282              (match_operand:SI 1 "const_int_operand" "")
20283              (match_operand:SI 2 "const_int_operand" ""))]
20284   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20286   int rw = INTVAL (operands[1]);
20287   int locality = INTVAL (operands[2]);
20289   gcc_assert (rw == 0 || rw == 1);
20290   gcc_assert (locality >= 0 && locality <= 3);
20291   gcc_assert (GET_MODE (operands[0]) == Pmode
20292               || GET_MODE (operands[0]) == VOIDmode);
20294   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20295      supported by SSE counterpart or the SSE prefetch is not available
20296      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20297      of locality.  */
20298   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20299     operands[2] = GEN_INT (3);
20300   else
20301     operands[1] = const0_rtx;
20304 (define_insn "*prefetch_sse"
20305   [(prefetch (match_operand:SI 0 "address_operand" "p")
20306              (const_int 0)
20307              (match_operand:SI 1 "const_int_operand" ""))]
20308   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20310   static const char * const patterns[4] = {
20311    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20312   };
20314   int locality = INTVAL (operands[1]);
20315   gcc_assert (locality >= 0 && locality <= 3);
20317   return patterns[locality];
20319   [(set_attr "type" "sse")
20320    (set_attr "memory" "none")])
20322 (define_insn "*prefetch_sse_rex"
20323   [(prefetch (match_operand:DI 0 "address_operand" "p")
20324              (const_int 0)
20325              (match_operand:SI 1 "const_int_operand" ""))]
20326   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20328   static const char * const patterns[4] = {
20329    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20330   };
20332   int locality = INTVAL (operands[1]);
20333   gcc_assert (locality >= 0 && locality <= 3);
20335   return patterns[locality];
20337   [(set_attr "type" "sse")
20338    (set_attr "memory" "none")])
20340 (define_insn "*prefetch_3dnow"
20341   [(prefetch (match_operand:SI 0 "address_operand" "p")
20342              (match_operand:SI 1 "const_int_operand" "n")
20343              (const_int 3))]
20344   "TARGET_3DNOW && !TARGET_64BIT"
20346   if (INTVAL (operands[1]) == 0)
20347     return "prefetch\t%a0";
20348   else
20349     return "prefetchw\t%a0";
20351   [(set_attr "type" "mmx")
20352    (set_attr "memory" "none")])
20354 (define_insn "*prefetch_3dnow_rex"
20355   [(prefetch (match_operand:DI 0 "address_operand" "p")
20356              (match_operand:SI 1 "const_int_operand" "n")
20357              (const_int 3))]
20358   "TARGET_3DNOW && TARGET_64BIT"
20360   if (INTVAL (operands[1]) == 0)
20361     return "prefetch\t%a0";
20362   else
20363     return "prefetchw\t%a0";
20365   [(set_attr "type" "mmx")
20366    (set_attr "memory" "none")])
20368 (define_expand "stack_protect_set"
20369   [(match_operand 0 "memory_operand" "")
20370    (match_operand 1 "memory_operand" "")]
20371   ""
20373 #ifdef TARGET_THREAD_SSP_OFFSET
20374   if (TARGET_64BIT)
20375     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20376                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20377   else
20378     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20379                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20380 #else
20381   if (TARGET_64BIT)
20382     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20383   else
20384     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20385 #endif
20386   DONE;
20389 (define_insn "stack_protect_set_si"
20390   [(set (match_operand:SI 0 "memory_operand" "=m")
20391         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20392    (set (match_scratch:SI 2 "=&r") (const_int 0))
20393    (clobber (reg:CC FLAGS_REG))]
20394   ""
20395   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20396   [(set_attr "type" "multi")])
20398 (define_insn "stack_protect_set_di"
20399   [(set (match_operand:DI 0 "memory_operand" "=m")
20400         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20401    (set (match_scratch:DI 2 "=&r") (const_int 0))
20402    (clobber (reg:CC FLAGS_REG))]
20403   "TARGET_64BIT"
20404   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20405   [(set_attr "type" "multi")])
20407 (define_insn "stack_tls_protect_set_si"
20408   [(set (match_operand:SI 0 "memory_operand" "=m")
20409         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20410    (set (match_scratch:SI 2 "=&r") (const_int 0))
20411    (clobber (reg:CC FLAGS_REG))]
20412   ""
20413   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20414   [(set_attr "type" "multi")])
20416 (define_insn "stack_tls_protect_set_di"
20417   [(set (match_operand:DI 0 "memory_operand" "=m")
20418         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20419    (set (match_scratch:DI 2 "=&r") (const_int 0))
20420    (clobber (reg:CC FLAGS_REG))]
20421   "TARGET_64BIT"
20422   {
20423      /* The kernel uses a different segment register for performance reasons; a
20424         system call would not have to trash the userspace segment register,
20425         which would be expensive */
20426      if (ix86_cmodel != CM_KERNEL)
20427         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20428      else
20429         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20430   }
20431   [(set_attr "type" "multi")])
20433 (define_expand "stack_protect_test"
20434   [(match_operand 0 "memory_operand" "")
20435    (match_operand 1 "memory_operand" "")
20436    (match_operand 2 "" "")]
20437   ""
20439   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20440   ix86_compare_op0 = operands[0];
20441   ix86_compare_op1 = operands[1];
20442   ix86_compare_emitted = flags;
20444 #ifdef TARGET_THREAD_SSP_OFFSET
20445   if (TARGET_64BIT)
20446     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20447                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20448   else
20449     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20450                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20451 #else
20452   if (TARGET_64BIT)
20453     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20454   else
20455     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20456 #endif
20457   emit_jump_insn (gen_beq (operands[2]));
20458   DONE;
20461 (define_insn "stack_protect_test_si"
20462   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20463         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20464                      (match_operand:SI 2 "memory_operand" "m")]
20465                     UNSPEC_SP_TEST))
20466    (clobber (match_scratch:SI 3 "=&r"))]
20467   ""
20468   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20469   [(set_attr "type" "multi")])
20471 (define_insn "stack_protect_test_di"
20472   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20473         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20474                      (match_operand:DI 2 "memory_operand" "m")]
20475                     UNSPEC_SP_TEST))
20476    (clobber (match_scratch:DI 3 "=&r"))]
20477   "TARGET_64BIT"
20478   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20479   [(set_attr "type" "multi")])
20481 (define_insn "stack_tls_protect_test_si"
20482   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20483         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20484                      (match_operand:SI 2 "const_int_operand" "i")]
20485                     UNSPEC_SP_TLS_TEST))
20486    (clobber (match_scratch:SI 3 "=r"))]
20487   ""
20488   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20489   [(set_attr "type" "multi")])
20491 (define_insn "stack_tls_protect_test_di"
20492   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20493         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20494                      (match_operand:DI 2 "const_int_operand" "i")]
20495                     UNSPEC_SP_TLS_TEST))
20496    (clobber (match_scratch:DI 3 "=r"))]
20497   "TARGET_64BIT"
20498   {
20499      /* The kernel uses a different segment register for performance reasons; a
20500         system call would not have to trash the userspace segment register,
20501         which would be expensive */
20502      if (ix86_cmodel != CM_KERNEL)
20503         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20504      else
20505         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20506   }
20507   [(set_attr "type" "multi")])
20509 (include "mmx.md")
20510 (include "sse.md")
20511 (include "sync.md")