2007-05-30 H.J. Lu <hongjiu.lu@intel.com>
[official-gcc.git] / gcc / config / i386 / i386.md
blob3912fb6e4ab1a2ce73f31d67b7370972a8695c07
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 ;; The special asm out single letter directives following a '%' are:
31 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;;     operands[1].
33 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
34 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
35 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
36 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
37 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
38 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
39 ;; 'J' Print the appropriate jump operand.
41 ;; 'b' Print the QImode name of the register for the indicated operand.
42 ;;     %b0 would print %al if operands[0] is reg 0.
43 ;; 'w' Likewise, print the HImode name of the register.
44 ;; 'k' Likewise, print the SImode name of the register.
45 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
46 ;; 'y' Print "st(0)" instead of "st" as a register.
48 ;; UNSPEC usage:
50 (define_constants
51   [; Relocation specifiers
52    (UNSPEC_GOT                  0)
53    (UNSPEC_GOTOFF               1)
54    (UNSPEC_GOTPCREL             2)
55    (UNSPEC_GOTTPOFF             3)
56    (UNSPEC_TPOFF                4)
57    (UNSPEC_NTPOFF               5)
58    (UNSPEC_DTPOFF               6)
59    (UNSPEC_GOTNTPOFF            7)
60    (UNSPEC_INDNTPOFF            8)
61    (UNSPEC_PLTOFF               9)
63    ; Prologue support
64    (UNSPEC_STACK_ALLOC          11)
65    (UNSPEC_SET_GOT              12)
66    (UNSPEC_SSE_PROLOGUE_SAVE    13)
67    (UNSPEC_REG_SAVE             14)
68    (UNSPEC_DEF_CFA              15)
69    (UNSPEC_SET_RIP              16)
70    (UNSPEC_SET_GOT_OFFSET       17)
72    ; TLS support
73    (UNSPEC_TP                   18)
74    (UNSPEC_TLS_GD               19)
75    (UNSPEC_TLS_LD_BASE          20)
76    (UNSPEC_TLSDESC              21)
78    ; Other random patterns
79    (UNSPEC_SCAS                 30)
80    (UNSPEC_FNSTSW               31)
81    (UNSPEC_SAHF                 32)
82    (UNSPEC_FSTCW                33)
83    (UNSPEC_ADD_CARRY            34)
84    (UNSPEC_FLDCW                35)
85    (UNSPEC_REP                  36)
86    (UNSPEC_EH_RETURN            37)
87    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
88    (UNSPEC_TRUNC_NOOP           39)
90    ; For SSE/MMX support:
91    (UNSPEC_FIX_NOTRUNC          40)
92    (UNSPEC_MASKMOV              41)
93    (UNSPEC_MOVMSK               42)
94    (UNSPEC_MOVNT                43)
95    (UNSPEC_MOVU                 44)
96    (UNSPEC_RCP                  45)
97    (UNSPEC_RSQRT                46)
98    (UNSPEC_SFENCE               47)
99    (UNSPEC_NOP                  48)     ; prevents combiner cleverness
100    (UNSPEC_PFRCP                49)
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)
125    (UNSPEC_FXAM                 69)
127    ; x87 Rounding
128    (UNSPEC_FRNDINT_FLOOR        70)
129    (UNSPEC_FRNDINT_CEIL         71)
130    (UNSPEC_FRNDINT_TRUNC        72)
131    (UNSPEC_FRNDINT_MASK_PM      73)
132    (UNSPEC_FIST_FLOOR           74)
133    (UNSPEC_FIST_CEIL            75)
135    ; x87 Double output FP
136    (UNSPEC_SINCOS_COS           80)
137    (UNSPEC_SINCOS_SIN           81)
138    (UNSPEC_XTRACT_FRACT         84)
139    (UNSPEC_XTRACT_EXP           85)
140    (UNSPEC_FSCALE_FRACT         86)
141    (UNSPEC_FSCALE_EXP           87)
142    (UNSPEC_FPREM_F              88)
143    (UNSPEC_FPREM_U              89)
144    (UNSPEC_FPREM1_F             90)
145    (UNSPEC_FPREM1_U             91)
147    (UNSPEC_C2_FLAG              95)
149    ; SSP patterns
150    (UNSPEC_SP_SET               100)
151    (UNSPEC_SP_TEST              101)
152    (UNSPEC_SP_TLS_SET           102)
153    (UNSPEC_SP_TLS_TEST          103)
155    ; SSSE3
156    (UNSPEC_PSHUFB               120)
157    (UNSPEC_PSIGN                121)
158    (UNSPEC_PALIGNR              122)
160    ; For SSE4A support
161    (UNSPEC_EXTRQI               130)
162    (UNSPEC_EXTRQ                131)   
163    (UNSPEC_INSERTQI             132)
164    (UNSPEC_INSERTQ              133)
166    ; For SSE4.1 support
167    (UNSPEC_BLENDV               134)
168    (UNSPEC_INSERTPS             135)
169    (UNSPEC_DP                   136)
170    (UNSPEC_MOVNTDQA             137)
171    (UNSPEC_MPSADBW              138)
172    (UNSPEC_PHMINPOSUW           139)
173    (UNSPEC_PTEST                140)
174    (UNSPEC_ROUNDP               141)
175    (UNSPEC_ROUNDS               142)
176   ])
178 (define_constants
179   [(UNSPECV_BLOCKAGE            0)
180    (UNSPECV_STACK_PROBE         1)
181    (UNSPECV_EMMS                2)
182    (UNSPECV_LDMXCSR             3)
183    (UNSPECV_STMXCSR             4)
184    (UNSPECV_FEMMS               5)
185    (UNSPECV_CLFLUSH             6)
186    (UNSPECV_ALIGN               7)
187    (UNSPECV_MONITOR             8)
188    (UNSPECV_MWAIT               9)
189    (UNSPECV_CMPXCHG_1           10)
190    (UNSPECV_CMPXCHG_2           11)
191    (UNSPECV_XCHG                12)
192    (UNSPECV_LOCK                13)
193   ])
195 ;; Registers by name.
196 (define_constants
197   [(BP_REG                       6)
198    (SP_REG                       7)
199    (FLAGS_REG                   17)
200    (FPSR_REG                    18)
201    (FPCR_REG                    19)
202    (R10_REG                     39)
203    (R11_REG                     40)
204   ])
206 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
207 ;; from i386.c.
209 ;; In C guard expressions, put expressions which may be compile-time
210 ;; constants first.  This allows for better optimization.  For
211 ;; example, write "TARGET_64BIT && reload_completed", not
212 ;; "reload_completed && TARGET_64BIT".
215 ;; Processor type.  This attribute must exactly match the processor_type
216 ;; enumeration in i386.h.
217 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
218                     nocona,core2,generic32,generic64,amdfam10"
219   (const (symbol_ref "ix86_tune")))
221 ;; A basic instruction type.  Refinements due to arguments to be
222 ;; provided in other attributes.
223 (define_attr "type"
224   "other,multi,
225    alu,alu1,negnot,imov,imovx,lea,
226    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
227    icmp,test,ibr,setcc,icmov,
228    push,pop,call,callv,leave,
229    str,bitmanip,
230    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
231    sselog,sselog1,sseiadd,sseishft,sseimul,
232    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
233    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
234   (const_string "other"))
236 ;; Main data type used by the insn
237 (define_attr "mode"
238   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
239   (const_string "unknown"))
241 ;; The CPU unit operations uses.
242 (define_attr "unit" "integer,i387,sse,mmx,unknown"
243   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
244            (const_string "i387")
245          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
246                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
247            (const_string "sse")
248          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
249            (const_string "mmx")
250          (eq_attr "type" "other")
251            (const_string "unknown")]
252          (const_string "integer")))
254 ;; The (bounding maximum) length of an instruction immediate.
255 (define_attr "length_immediate" ""
256   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
257                           bitmanip")
258            (const_int 0)
259          (eq_attr "unit" "i387,sse,mmx")
260            (const_int 0)
261          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
262                           imul,icmp,push,pop")
263            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
264          (eq_attr "type" "imov,test")
265            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
266          (eq_attr "type" "call")
267            (if_then_else (match_operand 0 "constant_call_address_operand" "")
268              (const_int 4)
269              (const_int 0))
270          (eq_attr "type" "callv")
271            (if_then_else (match_operand 1 "constant_call_address_operand" "")
272              (const_int 4)
273              (const_int 0))
274          ;; We don't know the size before shorten_branches.  Expect
275          ;; the instruction to fit for better scheduling.
276          (eq_attr "type" "ibr")
277            (const_int 1)
278          ]
279          (symbol_ref "/* Update immediate_length and other attributes! */
280                       gcc_unreachable (),1")))
282 ;; The (bounding maximum) length of an instruction address.
283 (define_attr "length_address" ""
284   (cond [(eq_attr "type" "str,other,multi,fxch")
285            (const_int 0)
286          (and (eq_attr "type" "call")
287               (match_operand 0 "constant_call_address_operand" ""))
288              (const_int 0)
289          (and (eq_attr "type" "callv")
290               (match_operand 1 "constant_call_address_operand" ""))
291              (const_int 0)
292          ]
293          (symbol_ref "ix86_attr_length_address_default (insn)")))
295 ;; Set when length prefix is used.
296 (define_attr "prefix_data16" ""
297   (if_then_else (ior (eq_attr "mode" "HI")
298                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
299     (const_int 1)
300     (const_int 0)))
302 ;; Set when string REP prefix is used.
303 (define_attr "prefix_rep" ""
304   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
305     (const_int 1)
306     (const_int 0)))
308 ;; Set when 0f opcode prefix is used.
309 (define_attr "prefix_0f" ""
310   (if_then_else
311     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
312          (eq_attr "unit" "sse,mmx"))
313     (const_int 1)
314     (const_int 0)))
316 ;; Set when REX opcode prefix is used.
317 (define_attr "prefix_rex" ""
318   (cond [(and (eq_attr "mode" "DI")
319               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
320            (const_int 1)
321          (and (eq_attr "mode" "QI")
322               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
323                   (const_int 0)))
324            (const_int 1)
325          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
326              (const_int 0))
327            (const_int 1)
328         ]
329         (const_int 0)))
331 ;; There are also additional prefixes in SSSE3.
332 (define_attr "prefix_extra" "" (const_int 0))
334 ;; Set when modrm byte is used.
335 (define_attr "modrm" ""
336   (cond [(eq_attr "type" "str,leave")
337            (const_int 0)
338          (eq_attr "unit" "i387")
339            (const_int 0)
340          (and (eq_attr "type" "incdec")
341               (ior (match_operand:SI 1 "register_operand" "")
342                    (match_operand:HI 1 "register_operand" "")))
343            (const_int 0)
344          (and (eq_attr "type" "push")
345               (not (match_operand 1 "memory_operand" "")))
346            (const_int 0)
347          (and (eq_attr "type" "pop")
348               (not (match_operand 0 "memory_operand" "")))
349            (const_int 0)
350          (and (eq_attr "type" "imov")
351               (ior (and (match_operand 0 "register_operand" "")
352                         (match_operand 1 "immediate_operand" ""))
353                    (ior (and (match_operand 0 "ax_reg_operand" "")
354                              (match_operand 1 "memory_displacement_only_operand" ""))
355                         (and (match_operand 0 "memory_displacement_only_operand" "")
356                              (match_operand 1 "ax_reg_operand" "")))))
357            (const_int 0)
358          (and (eq_attr "type" "call")
359               (match_operand 0 "constant_call_address_operand" ""))
360              (const_int 0)
361          (and (eq_attr "type" "callv")
362               (match_operand 1 "constant_call_address_operand" ""))
363              (const_int 0)
364          ]
365          (const_int 1)))
367 ;; The (bounding maximum) length of an instruction in bytes.
368 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
369 ;; Later we may want to split them and compute proper length as for
370 ;; other insns.
371 (define_attr "length" ""
372   (cond [(eq_attr "type" "other,multi,fistp,frndint")
373            (const_int 16)
374          (eq_attr "type" "fcmp")
375            (const_int 4)
376          (eq_attr "unit" "i387")
377            (plus (const_int 2)
378                  (plus (attr "prefix_data16")
379                        (attr "length_address")))]
380          (plus (plus (attr "modrm")
381                      (plus (attr "prefix_0f")
382                            (plus (attr "prefix_rex")
383                                  (plus (attr "prefix_extra")
384                                        (const_int 1)))))
385                (plus (attr "prefix_rep")
386                      (plus (attr "prefix_data16")
387                            (plus (attr "length_immediate")
388                                  (attr "length_address")))))))
390 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
391 ;; `store' if there is a simple memory reference therein, or `unknown'
392 ;; if the instruction is complex.
394 (define_attr "memory" "none,load,store,both,unknown"
395   (cond [(eq_attr "type" "other,multi,str")
396            (const_string "unknown")
397          (eq_attr "type" "lea,fcmov,fpspc")
398            (const_string "none")
399          (eq_attr "type" "fistp,leave")
400            (const_string "both")
401          (eq_attr "type" "frndint")
402            (const_string "load")
403          (eq_attr "type" "push")
404            (if_then_else (match_operand 1 "memory_operand" "")
405              (const_string "both")
406              (const_string "store"))
407          (eq_attr "type" "pop")
408            (if_then_else (match_operand 0 "memory_operand" "")
409              (const_string "both")
410              (const_string "load"))
411          (eq_attr "type" "setcc")
412            (if_then_else (match_operand 0 "memory_operand" "")
413              (const_string "store")
414              (const_string "none"))
415          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
416            (if_then_else (ior (match_operand 0 "memory_operand" "")
417                               (match_operand 1 "memory_operand" ""))
418              (const_string "load")
419              (const_string "none"))
420          (eq_attr "type" "ibr")
421            (if_then_else (match_operand 0 "memory_operand" "")
422              (const_string "load")
423              (const_string "none"))
424          (eq_attr "type" "call")
425            (if_then_else (match_operand 0 "constant_call_address_operand" "")
426              (const_string "none")
427              (const_string "load"))
428          (eq_attr "type" "callv")
429            (if_then_else (match_operand 1 "constant_call_address_operand" "")
430              (const_string "none")
431              (const_string "load"))
432          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
433               (match_operand 1 "memory_operand" ""))
434            (const_string "both")
435          (and (match_operand 0 "memory_operand" "")
436               (match_operand 1 "memory_operand" ""))
437            (const_string "both")
438          (match_operand 0 "memory_operand" "")
439            (const_string "store")
440          (match_operand 1 "memory_operand" "")
441            (const_string "load")
442          (and (eq_attr "type"
443                  "!alu1,negnot,ishift1,
444                    imov,imovx,icmp,test,bitmanip,
445                    fmov,fcmp,fsgn,
446                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
447                    mmx,mmxmov,mmxcmp,mmxcvt")
448               (match_operand 2 "memory_operand" ""))
449            (const_string "load")
450          (and (eq_attr "type" "icmov")
451               (match_operand 3 "memory_operand" ""))
452            (const_string "load")
453         ]
454         (const_string "none")))
456 ;; Indicates if an instruction has both an immediate and a displacement.
458 (define_attr "imm_disp" "false,true,unknown"
459   (cond [(eq_attr "type" "other,multi")
460            (const_string "unknown")
461          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
462               (and (match_operand 0 "memory_displacement_operand" "")
463                    (match_operand 1 "immediate_operand" "")))
464            (const_string "true")
465          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
466               (and (match_operand 0 "memory_displacement_operand" "")
467                    (match_operand 2 "immediate_operand" "")))
468            (const_string "true")
469         ]
470         (const_string "false")))
472 ;; Indicates if an FP operation has an integer source.
474 (define_attr "fp_int_src" "false,true"
475   (const_string "false"))
477 ;; Defines rounding mode of an FP operation.
479 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
480   (const_string "any"))
482 ;; Describe a user's asm statement.
483 (define_asm_attributes
484   [(set_attr "length" "128")
485    (set_attr "type" "multi")])
487 ;; All x87 floating point modes
488 (define_mode_macro X87MODEF [SF DF XF])
490 ;; x87 SFmode and DFMode floating point modes
491 (define_mode_macro X87MODEF12 [SF DF])
493 ;; All integer modes handled by x87 fisttp operator.
494 (define_mode_macro X87MODEI [HI SI DI])
496 ;; All integer modes handled by integer x87 operators.
497 (define_mode_macro X87MODEI12 [HI SI])
499 ;; All SSE floating point modes
500 (define_mode_macro SSEMODEF [SF DF])
502 ;; All integer modes handled by SSE cvtts?2si* operators.
503 (define_mode_macro SSEMODEI24 [SI DI])
505 ;; SSE asm suffix for floating point modes
506 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
508 ;; SSE vector mode corresponding to a scalar mode
509 (define_mode_attr ssevecmode
510   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
512 ;; Scheduling descriptions
514 (include "pentium.md")
515 (include "ppro.md")
516 (include "k6.md")
517 (include "athlon.md")
518 (include "geode.md")
521 ;; Operand and operator predicates and constraints
523 (include "predicates.md")
524 (include "constraints.md")
527 ;; Compare instructions.
529 ;; All compare insns have expanders that save the operands away without
530 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
531 ;; after the cmp) will actually emit the cmpM.
533 (define_expand "cmpti"
534   [(set (reg:CC FLAGS_REG)
535         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
536                     (match_operand:TI 1 "x86_64_general_operand" "")))]
537   "TARGET_64BIT"
539   if (MEM_P (operands[0]) && MEM_P (operands[1]))
540     operands[0] = force_reg (TImode, operands[0]);
541   ix86_compare_op0 = operands[0];
542   ix86_compare_op1 = operands[1];
543   DONE;
546 (define_expand "cmpdi"
547   [(set (reg:CC FLAGS_REG)
548         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
549                     (match_operand:DI 1 "x86_64_general_operand" "")))]
550   ""
552   if (MEM_P (operands[0]) && MEM_P (operands[1]))
553     operands[0] = force_reg (DImode, operands[0]);
554   ix86_compare_op0 = operands[0];
555   ix86_compare_op1 = operands[1];
556   DONE;
559 (define_expand "cmpsi"
560   [(set (reg:CC FLAGS_REG)
561         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
562                     (match_operand:SI 1 "general_operand" "")))]
563   ""
565   if (MEM_P (operands[0]) && MEM_P (operands[1]))
566     operands[0] = force_reg (SImode, operands[0]);
567   ix86_compare_op0 = operands[0];
568   ix86_compare_op1 = operands[1];
569   DONE;
572 (define_expand "cmphi"
573   [(set (reg:CC FLAGS_REG)
574         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
575                     (match_operand:HI 1 "general_operand" "")))]
576   ""
578   if (MEM_P (operands[0]) && MEM_P (operands[1]))
579     operands[0] = force_reg (HImode, operands[0]);
580   ix86_compare_op0 = operands[0];
581   ix86_compare_op1 = operands[1];
582   DONE;
585 (define_expand "cmpqi"
586   [(set (reg:CC FLAGS_REG)
587         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
588                     (match_operand:QI 1 "general_operand" "")))]
589   "TARGET_QIMODE_MATH"
591   if (MEM_P (operands[0]) && MEM_P (operands[1]))
592     operands[0] = force_reg (QImode, operands[0]);
593   ix86_compare_op0 = operands[0];
594   ix86_compare_op1 = operands[1];
595   DONE;
598 (define_insn "cmpdi_ccno_1_rex64"
599   [(set (reg FLAGS_REG)
600         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
601                  (match_operand:DI 1 "const0_operand" "n,n")))]
602   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
603   "@
604    test{q}\t%0, %0
605    cmp{q}\t{%1, %0|%0, %1}"
606   [(set_attr "type" "test,icmp")
607    (set_attr "length_immediate" "0,1")
608    (set_attr "mode" "DI")])
610 (define_insn "*cmpdi_minus_1_rex64"
611   [(set (reg FLAGS_REG)
612         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
613                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
614                  (const_int 0)))]
615   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
616   "cmp{q}\t{%1, %0|%0, %1}"
617   [(set_attr "type" "icmp")
618    (set_attr "mode" "DI")])
620 (define_expand "cmpdi_1_rex64"
621   [(set (reg:CC FLAGS_REG)
622         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
623                     (match_operand:DI 1 "general_operand" "")))]
624   "TARGET_64BIT"
625   "")
627 (define_insn "cmpdi_1_insn_rex64"
628   [(set (reg FLAGS_REG)
629         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
630                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
631   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
632   "cmp{q}\t{%1, %0|%0, %1}"
633   [(set_attr "type" "icmp")
634    (set_attr "mode" "DI")])
637 (define_insn "*cmpsi_ccno_1"
638   [(set (reg FLAGS_REG)
639         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
640                  (match_operand:SI 1 "const0_operand" "n,n")))]
641   "ix86_match_ccmode (insn, CCNOmode)"
642   "@
643    test{l}\t%0, %0
644    cmp{l}\t{%1, %0|%0, %1}"
645   [(set_attr "type" "test,icmp")
646    (set_attr "length_immediate" "0,1")
647    (set_attr "mode" "SI")])
649 (define_insn "*cmpsi_minus_1"
650   [(set (reg FLAGS_REG)
651         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
652                            (match_operand:SI 1 "general_operand" "ri,mr"))
653                  (const_int 0)))]
654   "ix86_match_ccmode (insn, CCGOCmode)"
655   "cmp{l}\t{%1, %0|%0, %1}"
656   [(set_attr "type" "icmp")
657    (set_attr "mode" "SI")])
659 (define_expand "cmpsi_1"
660   [(set (reg:CC FLAGS_REG)
661         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
662                     (match_operand:SI 1 "general_operand" "ri,mr")))]
663   ""
664   "")
666 (define_insn "*cmpsi_1_insn"
667   [(set (reg FLAGS_REG)
668         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
669                  (match_operand:SI 1 "general_operand" "ri,mr")))]
670   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
671     && ix86_match_ccmode (insn, CCmode)"
672   "cmp{l}\t{%1, %0|%0, %1}"
673   [(set_attr "type" "icmp")
674    (set_attr "mode" "SI")])
676 (define_insn "*cmphi_ccno_1"
677   [(set (reg FLAGS_REG)
678         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
679                  (match_operand:HI 1 "const0_operand" "n,n")))]
680   "ix86_match_ccmode (insn, CCNOmode)"
681   "@
682    test{w}\t%0, %0
683    cmp{w}\t{%1, %0|%0, %1}"
684   [(set_attr "type" "test,icmp")
685    (set_attr "length_immediate" "0,1")
686    (set_attr "mode" "HI")])
688 (define_insn "*cmphi_minus_1"
689   [(set (reg FLAGS_REG)
690         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
691                            (match_operand:HI 1 "general_operand" "ri,mr"))
692                  (const_int 0)))]
693   "ix86_match_ccmode (insn, CCGOCmode)"
694   "cmp{w}\t{%1, %0|%0, %1}"
695   [(set_attr "type" "icmp")
696    (set_attr "mode" "HI")])
698 (define_insn "*cmphi_1"
699   [(set (reg FLAGS_REG)
700         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
701                  (match_operand:HI 1 "general_operand" "ri,mr")))]
702   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
703    && ix86_match_ccmode (insn, CCmode)"
704   "cmp{w}\t{%1, %0|%0, %1}"
705   [(set_attr "type" "icmp")
706    (set_attr "mode" "HI")])
708 (define_insn "*cmpqi_ccno_1"
709   [(set (reg FLAGS_REG)
710         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
711                  (match_operand:QI 1 "const0_operand" "n,n")))]
712   "ix86_match_ccmode (insn, CCNOmode)"
713   "@
714    test{b}\t%0, %0
715    cmp{b}\t{$0, %0|%0, 0}"
716   [(set_attr "type" "test,icmp")
717    (set_attr "length_immediate" "0,1")
718    (set_attr "mode" "QI")])
720 (define_insn "*cmpqi_1"
721   [(set (reg FLAGS_REG)
722         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
723                  (match_operand:QI 1 "general_operand" "qi,mq")))]
724   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
725     && ix86_match_ccmode (insn, CCmode)"
726   "cmp{b}\t{%1, %0|%0, %1}"
727   [(set_attr "type" "icmp")
728    (set_attr "mode" "QI")])
730 (define_insn "*cmpqi_minus_1"
731   [(set (reg FLAGS_REG)
732         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
733                            (match_operand:QI 1 "general_operand" "qi,mq"))
734                  (const_int 0)))]
735   "ix86_match_ccmode (insn, CCGOCmode)"
736   "cmp{b}\t{%1, %0|%0, %1}"
737   [(set_attr "type" "icmp")
738    (set_attr "mode" "QI")])
740 (define_insn "*cmpqi_ext_1"
741   [(set (reg FLAGS_REG)
742         (compare
743           (match_operand:QI 0 "general_operand" "Qm")
744           (subreg:QI
745             (zero_extract:SI
746               (match_operand 1 "ext_register_operand" "Q")
747               (const_int 8)
748               (const_int 8)) 0)))]
749   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
750   "cmp{b}\t{%h1, %0|%0, %h1}"
751   [(set_attr "type" "icmp")
752    (set_attr "mode" "QI")])
754 (define_insn "*cmpqi_ext_1_rex64"
755   [(set (reg FLAGS_REG)
756         (compare
757           (match_operand:QI 0 "register_operand" "Q")
758           (subreg:QI
759             (zero_extract:SI
760               (match_operand 1 "ext_register_operand" "Q")
761               (const_int 8)
762               (const_int 8)) 0)))]
763   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
764   "cmp{b}\t{%h1, %0|%0, %h1}"
765   [(set_attr "type" "icmp")
766    (set_attr "mode" "QI")])
768 (define_insn "*cmpqi_ext_2"
769   [(set (reg FLAGS_REG)
770         (compare
771           (subreg:QI
772             (zero_extract:SI
773               (match_operand 0 "ext_register_operand" "Q")
774               (const_int 8)
775               (const_int 8)) 0)
776           (match_operand:QI 1 "const0_operand" "n")))]
777   "ix86_match_ccmode (insn, CCNOmode)"
778   "test{b}\t%h0, %h0"
779   [(set_attr "type" "test")
780    (set_attr "length_immediate" "0")
781    (set_attr "mode" "QI")])
783 (define_expand "cmpqi_ext_3"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC
786           (subreg:QI
787             (zero_extract:SI
788               (match_operand 0 "ext_register_operand" "")
789               (const_int 8)
790               (const_int 8)) 0)
791           (match_operand:QI 1 "general_operand" "")))]
792   ""
793   "")
795 (define_insn "cmpqi_ext_3_insn"
796   [(set (reg FLAGS_REG)
797         (compare
798           (subreg:QI
799             (zero_extract:SI
800               (match_operand 0 "ext_register_operand" "Q")
801               (const_int 8)
802               (const_int 8)) 0)
803           (match_operand:QI 1 "general_operand" "Qmn")))]
804   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
805   "cmp{b}\t{%1, %h0|%h0, %1}"
806   [(set_attr "type" "icmp")
807    (set_attr "mode" "QI")])
809 (define_insn "cmpqi_ext_3_insn_rex64"
810   [(set (reg FLAGS_REG)
811         (compare
812           (subreg:QI
813             (zero_extract:SI
814               (match_operand 0 "ext_register_operand" "Q")
815               (const_int 8)
816               (const_int 8)) 0)
817           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
818   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
819   "cmp{b}\t{%1, %h0|%h0, %1}"
820   [(set_attr "type" "icmp")
821    (set_attr "mode" "QI")])
823 (define_insn "*cmpqi_ext_4"
824   [(set (reg FLAGS_REG)
825         (compare
826           (subreg:QI
827             (zero_extract:SI
828               (match_operand 0 "ext_register_operand" "Q")
829               (const_int 8)
830               (const_int 8)) 0)
831           (subreg:QI
832             (zero_extract:SI
833               (match_operand 1 "ext_register_operand" "Q")
834               (const_int 8)
835               (const_int 8)) 0)))]
836   "ix86_match_ccmode (insn, CCmode)"
837   "cmp{b}\t{%h1, %h0|%h0, %h1}"
838   [(set_attr "type" "icmp")
839    (set_attr "mode" "QI")])
841 ;; These implement float point compares.
842 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
843 ;; which would allow mix and match FP modes on the compares.  Which is what
844 ;; the old patterns did, but with many more of them.
846 (define_expand "cmpxf"
847   [(set (reg:CC FLAGS_REG)
848         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
849                     (match_operand:XF 1 "nonmemory_operand" "")))]
850   "TARGET_80387"
852   ix86_compare_op0 = operands[0];
853   ix86_compare_op1 = operands[1];
854   DONE;
857 (define_expand "cmp<mode>"
858   [(set (reg:CC FLAGS_REG)
859         (compare:CC (match_operand:SSEMODEF 0 "cmp_fp_expander_operand" "")
860                     (match_operand:SSEMODEF 1 "cmp_fp_expander_operand" "")))]
861   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
863   ix86_compare_op0 = operands[0];
864   ix86_compare_op1 = operands[1];
865   DONE;
868 ;; FP compares, step 1:
869 ;; Set the FP condition codes.
871 ;; CCFPmode     compare with exceptions
872 ;; CCFPUmode    compare with no exceptions
874 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
875 ;; used to manage the reg stack popping would not be preserved.
877 (define_insn "*cmpfp_0"
878   [(set (match_operand:HI 0 "register_operand" "=a")
879         (unspec:HI
880           [(compare:CCFP
881              (match_operand 1 "register_operand" "f")
882              (match_operand 2 "const0_operand" "X"))]
883         UNSPEC_FNSTSW))]
884   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
885    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
886   "* return output_fp_compare (insn, operands, 0, 0);"
887   [(set_attr "type" "multi")
888    (set_attr "unit" "i387")
889    (set (attr "mode")
890      (cond [(match_operand:SF 1 "" "")
891               (const_string "SF")
892             (match_operand:DF 1 "" "")
893               (const_string "DF")
894            ]
895            (const_string "XF")))])
897 (define_insn "*cmpfp_xf"
898   [(set (match_operand:HI 0 "register_operand" "=a")
899         (unspec:HI
900           [(compare:CCFP
901              (match_operand:XF 1 "register_operand" "f")
902              (match_operand:XF 2 "register_operand" "f"))]
903           UNSPEC_FNSTSW))]
904   "TARGET_80387"
905   "* return output_fp_compare (insn, operands, 0, 0);"
906   [(set_attr "type" "multi")
907    (set_attr "unit" "i387")
908    (set_attr "mode" "XF")])
910 (define_insn "*cmpfp_<mode>"
911   [(set (match_operand:HI 0 "register_operand" "=a")
912         (unspec:HI
913           [(compare:CCFP
914              (match_operand:X87MODEF12 1 "register_operand" "f")
915              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm"))]
916           UNSPEC_FNSTSW))]
917   "TARGET_80387"
918   "* return output_fp_compare (insn, operands, 0, 0);"
919   [(set_attr "type" "multi")
920    (set_attr "unit" "i387")
921    (set_attr "mode" "<MODE>")])
923 (define_insn "*cmpfp_u"
924   [(set (match_operand:HI 0 "register_operand" "=a")
925         (unspec:HI
926           [(compare:CCFPU
927              (match_operand 1 "register_operand" "f")
928              (match_operand 2 "register_operand" "f"))]
929           UNSPEC_FNSTSW))]
930   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
931    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
932   "* return output_fp_compare (insn, operands, 0, 1);"
933   [(set_attr "type" "multi")
934    (set_attr "unit" "i387")
935    (set (attr "mode")
936      (cond [(match_operand:SF 1 "" "")
937               (const_string "SF")
938             (match_operand:DF 1 "" "")
939               (const_string "DF")
940            ]
941            (const_string "XF")))])
943 (define_insn "*cmpfp_<mode>"
944   [(set (match_operand:HI 0 "register_operand" "=a")
945         (unspec:HI
946           [(compare:CCFP
947              (match_operand 1 "register_operand" "f")
948              (match_operator 3 "float_operator"
949                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
950           UNSPEC_FNSTSW))]
951   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
952    && TARGET_USE_<MODE>MODE_FIOP
953    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
954   "* return output_fp_compare (insn, operands, 0, 0);"
955   [(set_attr "type" "multi")
956    (set_attr "unit" "i387")
957    (set_attr "fp_int_src" "true")
958    (set_attr "mode" "<MODE>")])
960 ;; FP compares, step 2
961 ;; Move the fpsw to ax.
963 (define_insn "x86_fnstsw_1"
964   [(set (match_operand:HI 0 "register_operand" "=a")
965         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
966   "TARGET_80387"
967   "fnstsw\t%0"
968   [(set_attr "length" "2")
969    (set_attr "mode" "SI")
970    (set_attr "unit" "i387")])
972 ;; FP compares, step 3
973 ;; Get ax into flags, general case.
975 (define_insn "x86_sahf_1"
976   [(set (reg:CC FLAGS_REG)
977         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
978                    UNSPEC_SAHF))]
979   "TARGET_SAHF"
981 #ifdef HAVE_AS_IX86_SAHF
982   return "sahf";
983 #else
984   return ".byte\t0x9e";
985 #endif
987   [(set_attr "length" "1")
988    (set_attr "athlon_decode" "vector")
989    (set_attr "amdfam10_decode" "direct")
990    (set_attr "mode" "SI")])
992 ;; Pentium Pro can do steps 1 through 3 in one go.
993 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
994 (define_insn "*cmpfp_i_mixed"
995   [(set (reg:CCFP FLAGS_REG)
996         (compare:CCFP (match_operand 0 "register_operand" "f,x")
997                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
998   "TARGET_MIX_SSE_I387
999    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1000    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1001   "* return output_fp_compare (insn, operands, 1, 0);"
1002   [(set_attr "type" "fcmp,ssecomi")
1003    (set (attr "mode")
1004      (if_then_else (match_operand:SF 1 "" "")
1005         (const_string "SF")
1006         (const_string "DF")))
1007    (set_attr "athlon_decode" "vector")
1008    (set_attr "amdfam10_decode" "direct")])
1010 (define_insn "*cmpfp_i_sse"
1011   [(set (reg:CCFP FLAGS_REG)
1012         (compare:CCFP (match_operand 0 "register_operand" "x")
1013                       (match_operand 1 "nonimmediate_operand" "xm")))]
1014   "TARGET_SSE_MATH
1015    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1016    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1017   "* return output_fp_compare (insn, operands, 1, 0);"
1018   [(set_attr "type" "ssecomi")
1019    (set (attr "mode")
1020      (if_then_else (match_operand:SF 1 "" "")
1021         (const_string "SF")
1022         (const_string "DF")))
1023    (set_attr "athlon_decode" "vector")
1024    (set_attr "amdfam10_decode" "direct")])
1026 (define_insn "*cmpfp_i_i387"
1027   [(set (reg:CCFP FLAGS_REG)
1028         (compare:CCFP (match_operand 0 "register_operand" "f")
1029                       (match_operand 1 "register_operand" "f")))]
1030   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1031    && TARGET_CMOVE
1032    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1033    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034   "* return output_fp_compare (insn, operands, 1, 0);"
1035   [(set_attr "type" "fcmp")
1036    (set (attr "mode")
1037      (cond [(match_operand:SF 1 "" "")
1038               (const_string "SF")
1039             (match_operand:DF 1 "" "")
1040               (const_string "DF")
1041            ]
1042            (const_string "XF")))
1043    (set_attr "athlon_decode" "vector")
1044    (set_attr "amdfam10_decode" "direct")])
1046 (define_insn "*cmpfp_iu_mixed"
1047   [(set (reg:CCFPU FLAGS_REG)
1048         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1049                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1050   "TARGET_MIX_SSE_I387
1051    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1052    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1053   "* return output_fp_compare (insn, operands, 1, 1);"
1054   [(set_attr "type" "fcmp,ssecomi")
1055    (set (attr "mode")
1056      (if_then_else (match_operand:SF 1 "" "")
1057         (const_string "SF")
1058         (const_string "DF")))
1059    (set_attr "athlon_decode" "vector")
1060    (set_attr "amdfam10_decode" "direct")])
1062 (define_insn "*cmpfp_iu_sse"
1063   [(set (reg:CCFPU FLAGS_REG)
1064         (compare:CCFPU (match_operand 0 "register_operand" "x")
1065                        (match_operand 1 "nonimmediate_operand" "xm")))]
1066   "TARGET_SSE_MATH
1067    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1068    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1069   "* return output_fp_compare (insn, operands, 1, 1);"
1070   [(set_attr "type" "ssecomi")
1071    (set (attr "mode")
1072      (if_then_else (match_operand:SF 1 "" "")
1073         (const_string "SF")
1074         (const_string "DF")))
1075    (set_attr "athlon_decode" "vector")
1076    (set_attr "amdfam10_decode" "direct")])
1078 (define_insn "*cmpfp_iu_387"
1079   [(set (reg:CCFPU FLAGS_REG)
1080         (compare:CCFPU (match_operand 0 "register_operand" "f")
1081                        (match_operand 1 "register_operand" "f")))]
1082   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1083    && TARGET_CMOVE
1084    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1085    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1086   "* return output_fp_compare (insn, operands, 1, 1);"
1087   [(set_attr "type" "fcmp")
1088    (set (attr "mode")
1089      (cond [(match_operand:SF 1 "" "")
1090               (const_string "SF")
1091             (match_operand:DF 1 "" "")
1092               (const_string "DF")
1093            ]
1094            (const_string "XF")))
1095    (set_attr "athlon_decode" "vector")
1096    (set_attr "amdfam10_decode" "direct")])
1098 ;; Move instructions.
1100 ;; General case of fullword move.
1102 (define_expand "movsi"
1103   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1104         (match_operand:SI 1 "general_operand" ""))]
1105   ""
1106   "ix86_expand_move (SImode, operands); DONE;")
1108 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1109 ;; general_operand.
1111 ;; %%% We don't use a post-inc memory reference because x86 is not a
1112 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1113 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1114 ;; targets without our curiosities, and it is just as easy to represent
1115 ;; this differently.
1117 (define_insn "*pushsi2"
1118   [(set (match_operand:SI 0 "push_operand" "=<")
1119         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1120   "!TARGET_64BIT"
1121   "push{l}\t%1"
1122   [(set_attr "type" "push")
1123    (set_attr "mode" "SI")])
1125 ;; For 64BIT abi we always round up to 8 bytes.
1126 (define_insn "*pushsi2_rex64"
1127   [(set (match_operand:SI 0 "push_operand" "=X")
1128         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1129   "TARGET_64BIT"
1130   "push{q}\t%q1"
1131   [(set_attr "type" "push")
1132    (set_attr "mode" "SI")])
1134 (define_insn "*pushsi2_prologue"
1135   [(set (match_operand:SI 0 "push_operand" "=<")
1136         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1137    (clobber (mem:BLK (scratch)))]
1138   "!TARGET_64BIT"
1139   "push{l}\t%1"
1140   [(set_attr "type" "push")
1141    (set_attr "mode" "SI")])
1143 (define_insn "*popsi1_epilogue"
1144   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1145         (mem:SI (reg:SI SP_REG)))
1146    (set (reg:SI SP_REG)
1147         (plus:SI (reg:SI SP_REG) (const_int 4)))
1148    (clobber (mem:BLK (scratch)))]
1149   "!TARGET_64BIT"
1150   "pop{l}\t%0"
1151   [(set_attr "type" "pop")
1152    (set_attr "mode" "SI")])
1154 (define_insn "popsi1"
1155   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1156         (mem:SI (reg:SI SP_REG)))
1157    (set (reg:SI SP_REG)
1158         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1159   "!TARGET_64BIT"
1160   "pop{l}\t%0"
1161   [(set_attr "type" "pop")
1162    (set_attr "mode" "SI")])
1164 (define_insn "*movsi_xor"
1165   [(set (match_operand:SI 0 "register_operand" "=r")
1166         (match_operand:SI 1 "const0_operand" "i"))
1167    (clobber (reg:CC FLAGS_REG))]
1168   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1169   "xor{l}\t%0, %0"
1170   [(set_attr "type" "alu1")
1171    (set_attr "mode" "SI")
1172    (set_attr "length_immediate" "0")])
1174 (define_insn "*movsi_or"
1175   [(set (match_operand:SI 0 "register_operand" "=r")
1176         (match_operand:SI 1 "immediate_operand" "i"))
1177    (clobber (reg:CC FLAGS_REG))]
1178   "reload_completed
1179    && operands[1] == constm1_rtx
1180    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1182   operands[1] = constm1_rtx;
1183   return "or{l}\t{%1, %0|%0, %1}";
1185   [(set_attr "type" "alu1")
1186    (set_attr "mode" "SI")
1187    (set_attr "length_immediate" "1")])
1189 (define_insn "*movsi_1"
1190   [(set (match_operand:SI 0 "nonimmediate_operand"
1191                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1192         (match_operand:SI 1 "general_operand"
1193                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1194   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1196   switch (get_attr_type (insn))
1197     {
1198     case TYPE_SSELOG1:
1199       if (get_attr_mode (insn) == MODE_TI)
1200         return "pxor\t%0, %0";
1201       return "xorps\t%0, %0";
1203     case TYPE_SSEMOV:
1204       switch (get_attr_mode (insn))
1205         {
1206         case MODE_TI:
1207           return "movdqa\t{%1, %0|%0, %1}";
1208         case MODE_V4SF:
1209           return "movaps\t{%1, %0|%0, %1}";
1210         case MODE_SI:
1211           return "movd\t{%1, %0|%0, %1}";
1212         case MODE_SF:
1213           return "movss\t{%1, %0|%0, %1}";
1214         default:
1215           gcc_unreachable ();
1216         }
1218     case TYPE_MMXADD:
1219       return "pxor\t%0, %0";
1221     case TYPE_MMXMOV:
1222       if (get_attr_mode (insn) == MODE_DI)
1223         return "movq\t{%1, %0|%0, %1}";
1224       return "movd\t{%1, %0|%0, %1}";
1226     case TYPE_LEA:
1227       return "lea{l}\t{%1, %0|%0, %1}";
1229     default:
1230       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1231       return "mov{l}\t{%1, %0|%0, %1}";
1232     }
1234   [(set (attr "type")
1235      (cond [(eq_attr "alternative" "2")
1236               (const_string "mmxadd")
1237             (eq_attr "alternative" "3,4,5")
1238               (const_string "mmxmov")
1239             (eq_attr "alternative" "6")
1240               (const_string "sselog1")
1241             (eq_attr "alternative" "7,8,9,10,11")
1242               (const_string "ssemov")
1243             (match_operand:DI 1 "pic_32bit_operand" "")
1244               (const_string "lea")
1245            ]
1246            (const_string "imov")))
1247    (set (attr "mode")
1248      (cond [(eq_attr "alternative" "2,3")
1249               (const_string "DI")
1250             (eq_attr "alternative" "6,7")
1251               (if_then_else
1252                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1253                 (const_string "V4SF")
1254                 (const_string "TI"))
1255             (and (eq_attr "alternative" "8,9,10,11")
1256                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1257               (const_string "SF")
1258            ]
1259            (const_string "SI")))])
1261 ;; Stores and loads of ax to arbitrary constant address.
1262 ;; We fake an second form of instruction to force reload to load address
1263 ;; into register when rax is not available
1264 (define_insn "*movabssi_1_rex64"
1265   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1266         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1267   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1268   "@
1269    movabs{l}\t{%1, %P0|%P0, %1}
1270    mov{l}\t{%1, %a0|%a0, %1}"
1271   [(set_attr "type" "imov")
1272    (set_attr "modrm" "0,*")
1273    (set_attr "length_address" "8,0")
1274    (set_attr "length_immediate" "0,*")
1275    (set_attr "memory" "store")
1276    (set_attr "mode" "SI")])
1278 (define_insn "*movabssi_2_rex64"
1279   [(set (match_operand:SI 0 "register_operand" "=a,r")
1280         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1281   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1282   "@
1283    movabs{l}\t{%P1, %0|%0, %P1}
1284    mov{l}\t{%a1, %0|%0, %a1}"
1285   [(set_attr "type" "imov")
1286    (set_attr "modrm" "0,*")
1287    (set_attr "length_address" "8,0")
1288    (set_attr "length_immediate" "0")
1289    (set_attr "memory" "load")
1290    (set_attr "mode" "SI")])
1292 (define_insn "*swapsi"
1293   [(set (match_operand:SI 0 "register_operand" "+r")
1294         (match_operand:SI 1 "register_operand" "+r"))
1295    (set (match_dup 1)
1296         (match_dup 0))]
1297   ""
1298   "xchg{l}\t%1, %0"
1299   [(set_attr "type" "imov")
1300    (set_attr "mode" "SI")
1301    (set_attr "pent_pair" "np")
1302    (set_attr "athlon_decode" "vector")
1303    (set_attr "amdfam10_decode" "double")])   
1305 (define_expand "movhi"
1306   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1307         (match_operand:HI 1 "general_operand" ""))]
1308   ""
1309   "ix86_expand_move (HImode, operands); DONE;")
1311 (define_insn "*pushhi2"
1312   [(set (match_operand:HI 0 "push_operand" "=X")
1313         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1314   "!TARGET_64BIT"
1315   "push{l}\t%k1"
1316   [(set_attr "type" "push")
1317    (set_attr "mode" "SI")])
1319 ;; For 64BIT abi we always round up to 8 bytes.
1320 (define_insn "*pushhi2_rex64"
1321   [(set (match_operand:HI 0 "push_operand" "=X")
1322         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1323   "TARGET_64BIT"
1324   "push{q}\t%q1"
1325   [(set_attr "type" "push")
1326    (set_attr "mode" "DI")])
1328 (define_insn "*movhi_1"
1329   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1330         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1331   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1333   switch (get_attr_type (insn))
1334     {
1335     case TYPE_IMOVX:
1336       /* movzwl is faster than movw on p2 due to partial word stalls,
1337          though not as fast as an aligned movl.  */
1338       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1339     default:
1340       if (get_attr_mode (insn) == MODE_SI)
1341         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1342       else
1343         return "mov{w}\t{%1, %0|%0, %1}";
1344     }
1346   [(set (attr "type")
1347      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1348               (const_string "imov")
1349             (and (eq_attr "alternative" "0")
1350                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1351                           (const_int 0))
1352                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1353                           (const_int 0))))
1354               (const_string "imov")
1355             (and (eq_attr "alternative" "1,2")
1356                  (match_operand:HI 1 "aligned_operand" ""))
1357               (const_string "imov")
1358             (and (ne (symbol_ref "TARGET_MOVX")
1359                      (const_int 0))
1360                  (eq_attr "alternative" "0,2"))
1361               (const_string "imovx")
1362            ]
1363            (const_string "imov")))
1364     (set (attr "mode")
1365       (cond [(eq_attr "type" "imovx")
1366                (const_string "SI")
1367              (and (eq_attr "alternative" "1,2")
1368                   (match_operand:HI 1 "aligned_operand" ""))
1369                (const_string "SI")
1370              (and (eq_attr "alternative" "0")
1371                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1372                            (const_int 0))
1373                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1374                            (const_int 0))))
1375                (const_string "SI")
1376             ]
1377             (const_string "HI")))])
1379 ;; Stores and loads of ax to arbitrary constant address.
1380 ;; We fake an second form of instruction to force reload to load address
1381 ;; into register when rax is not available
1382 (define_insn "*movabshi_1_rex64"
1383   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1384         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1385   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1386   "@
1387    movabs{w}\t{%1, %P0|%P0, %1}
1388    mov{w}\t{%1, %a0|%a0, %1}"
1389   [(set_attr "type" "imov")
1390    (set_attr "modrm" "0,*")
1391    (set_attr "length_address" "8,0")
1392    (set_attr "length_immediate" "0,*")
1393    (set_attr "memory" "store")
1394    (set_attr "mode" "HI")])
1396 (define_insn "*movabshi_2_rex64"
1397   [(set (match_operand:HI 0 "register_operand" "=a,r")
1398         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1399   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1400   "@
1401    movabs{w}\t{%P1, %0|%0, %P1}
1402    mov{w}\t{%a1, %0|%0, %a1}"
1403   [(set_attr "type" "imov")
1404    (set_attr "modrm" "0,*")
1405    (set_attr "length_address" "8,0")
1406    (set_attr "length_immediate" "0")
1407    (set_attr "memory" "load")
1408    (set_attr "mode" "HI")])
1410 (define_insn "*swaphi_1"
1411   [(set (match_operand:HI 0 "register_operand" "+r")
1412         (match_operand:HI 1 "register_operand" "+r"))
1413    (set (match_dup 1)
1414         (match_dup 0))]
1415   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1416   "xchg{l}\t%k1, %k0"
1417   [(set_attr "type" "imov")
1418    (set_attr "mode" "SI")
1419    (set_attr "pent_pair" "np")
1420    (set_attr "athlon_decode" "vector")
1421    (set_attr "amdfam10_decode" "double")])   
1423 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1424 (define_insn "*swaphi_2"
1425   [(set (match_operand:HI 0 "register_operand" "+r")
1426         (match_operand:HI 1 "register_operand" "+r"))
1427    (set (match_dup 1)
1428         (match_dup 0))]
1429   "TARGET_PARTIAL_REG_STALL"
1430   "xchg{w}\t%1, %0"
1431   [(set_attr "type" "imov")
1432    (set_attr "mode" "HI")
1433    (set_attr "pent_pair" "np")
1434    (set_attr "athlon_decode" "vector")])
1436 (define_expand "movstricthi"
1437   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1438         (match_operand:HI 1 "general_operand" ""))]
1439   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1441   /* Don't generate memory->memory moves, go through a register */
1442   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1443     operands[1] = force_reg (HImode, operands[1]);
1446 (define_insn "*movstricthi_1"
1447   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1448         (match_operand:HI 1 "general_operand" "rn,m"))]
1449   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1450    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1451   "mov{w}\t{%1, %0|%0, %1}"
1452   [(set_attr "type" "imov")
1453    (set_attr "mode" "HI")])
1455 (define_insn "*movstricthi_xor"
1456   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1457         (match_operand:HI 1 "const0_operand" "i"))
1458    (clobber (reg:CC FLAGS_REG))]
1459   "reload_completed
1460    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1461   "xor{w}\t%0, %0"
1462   [(set_attr "type" "alu1")
1463    (set_attr "mode" "HI")
1464    (set_attr "length_immediate" "0")])
1466 (define_expand "movqi"
1467   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1468         (match_operand:QI 1 "general_operand" ""))]
1469   ""
1470   "ix86_expand_move (QImode, operands); DONE;")
1472 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1473 ;; "push a byte".  But actually we use pushl, which has the effect
1474 ;; of rounding the amount pushed up to a word.
1476 (define_insn "*pushqi2"
1477   [(set (match_operand:QI 0 "push_operand" "=X")
1478         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1479   "!TARGET_64BIT"
1480   "push{l}\t%k1"
1481   [(set_attr "type" "push")
1482    (set_attr "mode" "SI")])
1484 ;; For 64BIT abi we always round up to 8 bytes.
1485 (define_insn "*pushqi2_rex64"
1486   [(set (match_operand:QI 0 "push_operand" "=X")
1487         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1488   "TARGET_64BIT"
1489   "push{q}\t%q1"
1490   [(set_attr "type" "push")
1491    (set_attr "mode" "DI")])
1493 ;; Situation is quite tricky about when to choose full sized (SImode) move
1494 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1495 ;; partial register dependency machines (such as AMD Athlon), where QImode
1496 ;; moves issue extra dependency and for partial register stalls machines
1497 ;; that don't use QImode patterns (and QImode move cause stall on the next
1498 ;; instruction).
1500 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1501 ;; register stall machines with, where we use QImode instructions, since
1502 ;; partial register stall can be caused there.  Then we use movzx.
1503 (define_insn "*movqi_1"
1504   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1505         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1506   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1508   switch (get_attr_type (insn))
1509     {
1510     case TYPE_IMOVX:
1511       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1512       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1513     default:
1514       if (get_attr_mode (insn) == MODE_SI)
1515         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1516       else
1517         return "mov{b}\t{%1, %0|%0, %1}";
1518     }
1520   [(set (attr "type")
1521      (cond [(and (eq_attr "alternative" "5")
1522                  (not (match_operand:QI 1 "aligned_operand" "")))
1523               (const_string "imovx")
1524             (ne (symbol_ref "optimize_size") (const_int 0))
1525               (const_string "imov")
1526             (and (eq_attr "alternative" "3")
1527                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1528                           (const_int 0))
1529                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1530                           (const_int 0))))
1531               (const_string "imov")
1532             (eq_attr "alternative" "3,5")
1533               (const_string "imovx")
1534             (and (ne (symbol_ref "TARGET_MOVX")
1535                      (const_int 0))
1536                  (eq_attr "alternative" "2"))
1537               (const_string "imovx")
1538            ]
1539            (const_string "imov")))
1540    (set (attr "mode")
1541       (cond [(eq_attr "alternative" "3,4,5")
1542                (const_string "SI")
1543              (eq_attr "alternative" "6")
1544                (const_string "QI")
1545              (eq_attr "type" "imovx")
1546                (const_string "SI")
1547              (and (eq_attr "type" "imov")
1548                   (and (eq_attr "alternative" "0,1")
1549                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1550                                 (const_int 0))
1551                             (and (eq (symbol_ref "optimize_size")
1552                                      (const_int 0))
1553                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1554                                      (const_int 0))))))
1555                (const_string "SI")
1556              ;; Avoid partial register stalls when not using QImode arithmetic
1557              (and (eq_attr "type" "imov")
1558                   (and (eq_attr "alternative" "0,1")
1559                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1560                                 (const_int 0))
1561                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1562                                 (const_int 0)))))
1563                (const_string "SI")
1564            ]
1565            (const_string "QI")))])
1567 (define_expand "reload_outqi"
1568   [(parallel [(match_operand:QI 0 "" "=m")
1569               (match_operand:QI 1 "register_operand" "r")
1570               (match_operand:QI 2 "register_operand" "=&q")])]
1571   ""
1573   rtx op0, op1, op2;
1574   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1576   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1577   if (! q_regs_operand (op1, QImode))
1578     {
1579       emit_insn (gen_movqi (op2, op1));
1580       op1 = op2;
1581     }
1582   emit_insn (gen_movqi (op0, op1));
1583   DONE;
1586 (define_insn "*swapqi_1"
1587   [(set (match_operand:QI 0 "register_operand" "+r")
1588         (match_operand:QI 1 "register_operand" "+r"))
1589    (set (match_dup 1)
1590         (match_dup 0))]
1591   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1592   "xchg{l}\t%k1, %k0"
1593   [(set_attr "type" "imov")
1594    (set_attr "mode" "SI")
1595    (set_attr "pent_pair" "np")
1596    (set_attr "athlon_decode" "vector")
1597    (set_attr "amdfam10_decode" "vector")])   
1599 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1600 (define_insn "*swapqi_2"
1601   [(set (match_operand:QI 0 "register_operand" "+q")
1602         (match_operand:QI 1 "register_operand" "+q"))
1603    (set (match_dup 1)
1604         (match_dup 0))]
1605   "TARGET_PARTIAL_REG_STALL"
1606   "xchg{b}\t%1, %0"
1607   [(set_attr "type" "imov")
1608    (set_attr "mode" "QI")
1609    (set_attr "pent_pair" "np")
1610    (set_attr "athlon_decode" "vector")])
1612 (define_expand "movstrictqi"
1613   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1614         (match_operand:QI 1 "general_operand" ""))]
1615   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1617   /* Don't generate memory->memory moves, go through a register.  */
1618   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1619     operands[1] = force_reg (QImode, operands[1]);
1622 (define_insn "*movstrictqi_1"
1623   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1624         (match_operand:QI 1 "general_operand" "*qn,m"))]
1625   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1626    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1627   "mov{b}\t{%1, %0|%0, %1}"
1628   [(set_attr "type" "imov")
1629    (set_attr "mode" "QI")])
1631 (define_insn "*movstrictqi_xor"
1632   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1633         (match_operand:QI 1 "const0_operand" "i"))
1634    (clobber (reg:CC FLAGS_REG))]
1635   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1636   "xor{b}\t%0, %0"
1637   [(set_attr "type" "alu1")
1638    (set_attr "mode" "QI")
1639    (set_attr "length_immediate" "0")])
1641 (define_insn "*movsi_extv_1"
1642   [(set (match_operand:SI 0 "register_operand" "=R")
1643         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1644                          (const_int 8)
1645                          (const_int 8)))]
1646   ""
1647   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1648   [(set_attr "type" "imovx")
1649    (set_attr "mode" "SI")])
1651 (define_insn "*movhi_extv_1"
1652   [(set (match_operand:HI 0 "register_operand" "=R")
1653         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1654                          (const_int 8)
1655                          (const_int 8)))]
1656   ""
1657   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1658   [(set_attr "type" "imovx")
1659    (set_attr "mode" "SI")])
1661 (define_insn "*movqi_extv_1"
1662   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1663         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1664                          (const_int 8)
1665                          (const_int 8)))]
1666   "!TARGET_64BIT"
1668   switch (get_attr_type (insn))
1669     {
1670     case TYPE_IMOVX:
1671       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1672     default:
1673       return "mov{b}\t{%h1, %0|%0, %h1}";
1674     }
1676   [(set (attr "type")
1677      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1678                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1679                              (ne (symbol_ref "TARGET_MOVX")
1680                                  (const_int 0))))
1681         (const_string "imovx")
1682         (const_string "imov")))
1683    (set (attr "mode")
1684      (if_then_else (eq_attr "type" "imovx")
1685         (const_string "SI")
1686         (const_string "QI")))])
1688 (define_insn "*movqi_extv_1_rex64"
1689   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1690         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1691                          (const_int 8)
1692                          (const_int 8)))]
1693   "TARGET_64BIT"
1695   switch (get_attr_type (insn))
1696     {
1697     case TYPE_IMOVX:
1698       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1699     default:
1700       return "mov{b}\t{%h1, %0|%0, %h1}";
1701     }
1703   [(set (attr "type")
1704      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1705                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1706                              (ne (symbol_ref "TARGET_MOVX")
1707                                  (const_int 0))))
1708         (const_string "imovx")
1709         (const_string "imov")))
1710    (set (attr "mode")
1711      (if_then_else (eq_attr "type" "imovx")
1712         (const_string "SI")
1713         (const_string "QI")))])
1715 ;; Stores and loads of ax to arbitrary constant address.
1716 ;; We fake an second form of instruction to force reload to load address
1717 ;; into register when rax is not available
1718 (define_insn "*movabsqi_1_rex64"
1719   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1720         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1721   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1722   "@
1723    movabs{b}\t{%1, %P0|%P0, %1}
1724    mov{b}\t{%1, %a0|%a0, %1}"
1725   [(set_attr "type" "imov")
1726    (set_attr "modrm" "0,*")
1727    (set_attr "length_address" "8,0")
1728    (set_attr "length_immediate" "0,*")
1729    (set_attr "memory" "store")
1730    (set_attr "mode" "QI")])
1732 (define_insn "*movabsqi_2_rex64"
1733   [(set (match_operand:QI 0 "register_operand" "=a,r")
1734         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1735   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1736   "@
1737    movabs{b}\t{%P1, %0|%0, %P1}
1738    mov{b}\t{%a1, %0|%0, %a1}"
1739   [(set_attr "type" "imov")
1740    (set_attr "modrm" "0,*")
1741    (set_attr "length_address" "8,0")
1742    (set_attr "length_immediate" "0")
1743    (set_attr "memory" "load")
1744    (set_attr "mode" "QI")])
1746 (define_insn "*movdi_extzv_1"
1747   [(set (match_operand:DI 0 "register_operand" "=R")
1748         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1749                          (const_int 8)
1750                          (const_int 8)))]
1751   "TARGET_64BIT"
1752   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1753   [(set_attr "type" "imovx")
1754    (set_attr "mode" "DI")])
1756 (define_insn "*movsi_extzv_1"
1757   [(set (match_operand:SI 0 "register_operand" "=R")
1758         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1759                          (const_int 8)
1760                          (const_int 8)))]
1761   ""
1762   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1763   [(set_attr "type" "imovx")
1764    (set_attr "mode" "SI")])
1766 (define_insn "*movqi_extzv_2"
1767   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1768         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1769                                     (const_int 8)
1770                                     (const_int 8)) 0))]
1771   "!TARGET_64BIT"
1773   switch (get_attr_type (insn))
1774     {
1775     case TYPE_IMOVX:
1776       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1777     default:
1778       return "mov{b}\t{%h1, %0|%0, %h1}";
1779     }
1781   [(set (attr "type")
1782      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1783                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1784                              (ne (symbol_ref "TARGET_MOVX")
1785                                  (const_int 0))))
1786         (const_string "imovx")
1787         (const_string "imov")))
1788    (set (attr "mode")
1789      (if_then_else (eq_attr "type" "imovx")
1790         (const_string "SI")
1791         (const_string "QI")))])
1793 (define_insn "*movqi_extzv_2_rex64"
1794   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1795         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1796                                     (const_int 8)
1797                                     (const_int 8)) 0))]
1798   "TARGET_64BIT"
1800   switch (get_attr_type (insn))
1801     {
1802     case TYPE_IMOVX:
1803       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1804     default:
1805       return "mov{b}\t{%h1, %0|%0, %h1}";
1806     }
1808   [(set (attr "type")
1809      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1810                         (ne (symbol_ref "TARGET_MOVX")
1811                             (const_int 0)))
1812         (const_string "imovx")
1813         (const_string "imov")))
1814    (set (attr "mode")
1815      (if_then_else (eq_attr "type" "imovx")
1816         (const_string "SI")
1817         (const_string "QI")))])
1819 (define_insn "movsi_insv_1"
1820   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1821                          (const_int 8)
1822                          (const_int 8))
1823         (match_operand:SI 1 "general_operand" "Qmn"))]
1824   "!TARGET_64BIT"
1825   "mov{b}\t{%b1, %h0|%h0, %b1}"
1826   [(set_attr "type" "imov")
1827    (set_attr "mode" "QI")])
1829 (define_insn "*movsi_insv_1_rex64"
1830   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1831                          (const_int 8)
1832                          (const_int 8))
1833         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1834   "TARGET_64BIT"
1835   "mov{b}\t{%b1, %h0|%h0, %b1}"
1836   [(set_attr "type" "imov")
1837    (set_attr "mode" "QI")])
1839 (define_insn "movdi_insv_1_rex64"
1840   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1841                          (const_int 8)
1842                          (const_int 8))
1843         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1844   "TARGET_64BIT"
1845   "mov{b}\t{%b1, %h0|%h0, %b1}"
1846   [(set_attr "type" "imov")
1847    (set_attr "mode" "QI")])
1849 (define_insn "*movqi_insv_2"
1850   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1851                          (const_int 8)
1852                          (const_int 8))
1853         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1854                      (const_int 8)))]
1855   ""
1856   "mov{b}\t{%h1, %h0|%h0, %h1}"
1857   [(set_attr "type" "imov")
1858    (set_attr "mode" "QI")])
1860 (define_expand "movdi"
1861   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1862         (match_operand:DI 1 "general_operand" ""))]
1863   ""
1864   "ix86_expand_move (DImode, operands); DONE;")
1866 (define_insn "*pushdi"
1867   [(set (match_operand:DI 0 "push_operand" "=<")
1868         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1869   "!TARGET_64BIT"
1870   "#")
1872 (define_insn "*pushdi2_rex64"
1873   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1874         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1875   "TARGET_64BIT"
1876   "@
1877    push{q}\t%1
1878    #"
1879   [(set_attr "type" "push,multi")
1880    (set_attr "mode" "DI")])
1882 ;; Convert impossible pushes of immediate to existing instructions.
1883 ;; First try to get scratch register and go through it.  In case this
1884 ;; fails, push sign extended lower part first and then overwrite
1885 ;; upper part by 32bit move.
1886 (define_peephole2
1887   [(match_scratch:DI 2 "r")
1888    (set (match_operand:DI 0 "push_operand" "")
1889         (match_operand:DI 1 "immediate_operand" ""))]
1890   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1891    && !x86_64_immediate_operand (operands[1], DImode)"
1892   [(set (match_dup 2) (match_dup 1))
1893    (set (match_dup 0) (match_dup 2))]
1894   "")
1896 ;; We need to define this as both peepholer and splitter for case
1897 ;; peephole2 pass is not run.
1898 ;; "&& 1" is needed to keep it from matching the previous pattern.
1899 (define_peephole2
1900   [(set (match_operand:DI 0 "push_operand" "")
1901         (match_operand:DI 1 "immediate_operand" ""))]
1902   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1903    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1904   [(set (match_dup 0) (match_dup 1))
1905    (set (match_dup 2) (match_dup 3))]
1906   "split_di (operands + 1, 1, operands + 2, operands + 3);
1907    operands[1] = gen_lowpart (DImode, operands[2]);
1908    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1909                                                     GEN_INT (4)));
1910   ")
1912 (define_split
1913   [(set (match_operand:DI 0 "push_operand" "")
1914         (match_operand:DI 1 "immediate_operand" ""))]
1915   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1916                     ? flow2_completed : reload_completed)
1917    && !symbolic_operand (operands[1], DImode)
1918    && !x86_64_immediate_operand (operands[1], DImode)"
1919   [(set (match_dup 0) (match_dup 1))
1920    (set (match_dup 2) (match_dup 3))]
1921   "split_di (operands + 1, 1, operands + 2, operands + 3);
1922    operands[1] = gen_lowpart (DImode, operands[2]);
1923    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1924                                                     GEN_INT (4)));
1925   ")
1927 (define_insn "*pushdi2_prologue_rex64"
1928   [(set (match_operand:DI 0 "push_operand" "=<")
1929         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1930    (clobber (mem:BLK (scratch)))]
1931   "TARGET_64BIT"
1932   "push{q}\t%1"
1933   [(set_attr "type" "push")
1934    (set_attr "mode" "DI")])
1936 (define_insn "*popdi1_epilogue_rex64"
1937   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1938         (mem:DI (reg:DI SP_REG)))
1939    (set (reg:DI SP_REG)
1940         (plus:DI (reg:DI SP_REG) (const_int 8)))
1941    (clobber (mem:BLK (scratch)))]
1942   "TARGET_64BIT"
1943   "pop{q}\t%0"
1944   [(set_attr "type" "pop")
1945    (set_attr "mode" "DI")])
1947 (define_insn "popdi1"
1948   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1949         (mem:DI (reg:DI SP_REG)))
1950    (set (reg:DI SP_REG)
1951         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1952   "TARGET_64BIT"
1953   "pop{q}\t%0"
1954   [(set_attr "type" "pop")
1955    (set_attr "mode" "DI")])
1957 (define_insn "*movdi_xor_rex64"
1958   [(set (match_operand:DI 0 "register_operand" "=r")
1959         (match_operand:DI 1 "const0_operand" "i"))
1960    (clobber (reg:CC FLAGS_REG))]
1961   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1962    && reload_completed"
1963   "xor{l}\t%k0, %k0";
1964   [(set_attr "type" "alu1")
1965    (set_attr "mode" "SI")
1966    (set_attr "length_immediate" "0")])
1968 (define_insn "*movdi_or_rex64"
1969   [(set (match_operand:DI 0 "register_operand" "=r")
1970         (match_operand:DI 1 "const_int_operand" "i"))
1971    (clobber (reg:CC FLAGS_REG))]
1972   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
1973    && reload_completed
1974    && operands[1] == constm1_rtx"
1976   operands[1] = constm1_rtx;
1977   return "or{q}\t{%1, %0|%0, %1}";
1979   [(set_attr "type" "alu1")
1980    (set_attr "mode" "DI")
1981    (set_attr "length_immediate" "1")])
1983 (define_insn "*movdi_2"
1984   [(set (match_operand:DI 0 "nonimmediate_operand"
1985                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
1986         (match_operand:DI 1 "general_operand"
1987                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
1988   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1989   "@
1990    #
1991    #
1992    pxor\t%0, %0
1993    movq\t{%1, %0|%0, %1}
1994    movq\t{%1, %0|%0, %1}
1995    pxor\t%0, %0
1996    movq\t{%1, %0|%0, %1}
1997    movdqa\t{%1, %0|%0, %1}
1998    movq\t{%1, %0|%0, %1}
1999    xorps\t%0, %0
2000    movlps\t{%1, %0|%0, %1}
2001    movaps\t{%1, %0|%0, %1}
2002    movlps\t{%1, %0|%0, %1}"
2003   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2004    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2006 (define_split
2007   [(set (match_operand:DI 0 "push_operand" "")
2008         (match_operand:DI 1 "general_operand" ""))]
2009   "!TARGET_64BIT && reload_completed
2010    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2011   [(const_int 0)]
2012   "ix86_split_long_move (operands); DONE;")
2014 ;; %%% This multiword shite has got to go.
2015 (define_split
2016   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2017         (match_operand:DI 1 "general_operand" ""))]
2018   "!TARGET_64BIT && reload_completed
2019    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2020    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2021   [(const_int 0)]
2022   "ix86_split_long_move (operands); DONE;")
2024 (define_insn "*movdi_1_rex64"
2025   [(set (match_operand:DI 0 "nonimmediate_operand"
2026           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2027         (match_operand:DI 1 "general_operand"
2028           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2029   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2031   switch (get_attr_type (insn))
2032     {
2033     case TYPE_SSECVT:
2034       if (SSE_REG_P (operands[0]))
2035         return "movq2dq\t{%1, %0|%0, %1}";
2036       else
2037         return "movdq2q\t{%1, %0|%0, %1}";
2039     case TYPE_SSEMOV:
2040       if (get_attr_mode (insn) == MODE_TI)
2041         return "movdqa\t{%1, %0|%0, %1}";
2042       /* FALLTHRU */
2044     case TYPE_MMXMOV:
2045       /* Moves from and into integer register is done using movd
2046          opcode with REX prefix.  */
2047       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2048         return "movd\t{%1, %0|%0, %1}";
2049       return "movq\t{%1, %0|%0, %1}";
2051     case TYPE_SSELOG1:
2052     case TYPE_MMXADD:
2053       return "pxor\t%0, %0";
2055     case TYPE_MULTI:
2056       return "#";
2058     case TYPE_LEA:
2059       return "lea{q}\t{%a1, %0|%0, %a1}";
2061     default:
2062       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2063       if (get_attr_mode (insn) == MODE_SI)
2064         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2065       else if (which_alternative == 2)
2066         return "movabs{q}\t{%1, %0|%0, %1}";
2067       else
2068         return "mov{q}\t{%1, %0|%0, %1}";
2069     }
2071   [(set (attr "type")
2072      (cond [(eq_attr "alternative" "5")
2073               (const_string "mmxadd")
2074             (eq_attr "alternative" "6,7,8,9,10")
2075               (const_string "mmxmov")
2076             (eq_attr "alternative" "11")
2077               (const_string "sselog1")
2078             (eq_attr "alternative" "12,13,14,15,16")
2079               (const_string "ssemov")
2080             (eq_attr "alternative" "17,18")
2081               (const_string "ssecvt")
2082             (eq_attr "alternative" "4")
2083               (const_string "multi")
2084             (match_operand:DI 1 "pic_32bit_operand" "")
2085               (const_string "lea")
2086            ]
2087            (const_string "imov")))
2088    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2090    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2092 ;; Stores and loads of ax to arbitrary constant address.
2093 ;; We fake an second form of instruction to force reload to load address
2094 ;; into register when rax is not available
2095 (define_insn "*movabsdi_1_rex64"
2096   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2097         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2098   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2099   "@
2100    movabs{q}\t{%1, %P0|%P0, %1}
2101    mov{q}\t{%1, %a0|%a0, %1}"
2102   [(set_attr "type" "imov")
2103    (set_attr "modrm" "0,*")
2104    (set_attr "length_address" "8,0")
2105    (set_attr "length_immediate" "0,*")
2106    (set_attr "memory" "store")
2107    (set_attr "mode" "DI")])
2109 (define_insn "*movabsdi_2_rex64"
2110   [(set (match_operand:DI 0 "register_operand" "=a,r")
2111         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2112   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2113   "@
2114    movabs{q}\t{%P1, %0|%0, %P1}
2115    mov{q}\t{%a1, %0|%0, %a1}"
2116   [(set_attr "type" "imov")
2117    (set_attr "modrm" "0,*")
2118    (set_attr "length_address" "8,0")
2119    (set_attr "length_immediate" "0")
2120    (set_attr "memory" "load")
2121    (set_attr "mode" "DI")])
2123 ;; Convert impossible stores of immediate to existing instructions.
2124 ;; First try to get scratch register and go through it.  In case this
2125 ;; fails, move by 32bit parts.
2126 (define_peephole2
2127   [(match_scratch:DI 2 "r")
2128    (set (match_operand:DI 0 "memory_operand" "")
2129         (match_operand:DI 1 "immediate_operand" ""))]
2130   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2131    && !x86_64_immediate_operand (operands[1], DImode)"
2132   [(set (match_dup 2) (match_dup 1))
2133    (set (match_dup 0) (match_dup 2))]
2134   "")
2136 ;; We need to define this as both peepholer and splitter for case
2137 ;; peephole2 pass is not run.
2138 ;; "&& 1" is needed to keep it from matching the previous pattern.
2139 (define_peephole2
2140   [(set (match_operand:DI 0 "memory_operand" "")
2141         (match_operand:DI 1 "immediate_operand" ""))]
2142   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2143    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2144   [(set (match_dup 2) (match_dup 3))
2145    (set (match_dup 4) (match_dup 5))]
2146   "split_di (operands, 2, operands + 2, operands + 4);")
2148 (define_split
2149   [(set (match_operand:DI 0 "memory_operand" "")
2150         (match_operand:DI 1 "immediate_operand" ""))]
2151   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2152                     ? flow2_completed : reload_completed)
2153    && !symbolic_operand (operands[1], DImode)
2154    && !x86_64_immediate_operand (operands[1], DImode)"
2155   [(set (match_dup 2) (match_dup 3))
2156    (set (match_dup 4) (match_dup 5))]
2157   "split_di (operands, 2, operands + 2, operands + 4);")
2159 (define_insn "*swapdi_rex64"
2160   [(set (match_operand:DI 0 "register_operand" "+r")
2161         (match_operand:DI 1 "register_operand" "+r"))
2162    (set (match_dup 1)
2163         (match_dup 0))]
2164   "TARGET_64BIT"
2165   "xchg{q}\t%1, %0"
2166   [(set_attr "type" "imov")
2167    (set_attr "mode" "DI")
2168    (set_attr "pent_pair" "np")
2169    (set_attr "athlon_decode" "vector")
2170    (set_attr "amdfam10_decode" "double")])   
2172 (define_expand "movti"
2173   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2174         (match_operand:TI 1 "nonimmediate_operand" ""))]
2175   "TARGET_SSE || TARGET_64BIT"
2177   if (TARGET_64BIT)
2178     ix86_expand_move (TImode, operands);
2179   else if (push_operand (operands[0], TImode))
2180     ix86_expand_push (TImode, operands[1]);
2181   else
2182     ix86_expand_vector_move (TImode, operands);
2183   DONE;
2186 (define_insn "*movti_internal"
2187   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2188         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2189   "TARGET_SSE && !TARGET_64BIT
2190    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2192   switch (which_alternative)
2193     {
2194     case 0:
2195       if (get_attr_mode (insn) == MODE_V4SF)
2196         return "xorps\t%0, %0";
2197       else
2198         return "pxor\t%0, %0";
2199     case 1:
2200     case 2:
2201       if (get_attr_mode (insn) == MODE_V4SF)
2202         return "movaps\t{%1, %0|%0, %1}";
2203       else
2204         return "movdqa\t{%1, %0|%0, %1}";
2205     default:
2206       gcc_unreachable ();
2207     }
2209   [(set_attr "type" "sselog1,ssemov,ssemov")
2210    (set (attr "mode")
2211         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2212                     (ne (symbol_ref "optimize_size") (const_int 0)))
2213                  (const_string "V4SF")
2214                (and (eq_attr "alternative" "2")
2215                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2216                         (const_int 0)))
2217                  (const_string "V4SF")]
2218               (const_string "TI")))])
2220 (define_insn "*movti_rex64"
2221   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2222         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2223   "TARGET_64BIT
2224    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2226   switch (which_alternative)
2227     {
2228     case 0:
2229     case 1:
2230       return "#";
2231     case 2:
2232       if (get_attr_mode (insn) == MODE_V4SF)
2233         return "xorps\t%0, %0";
2234       else
2235         return "pxor\t%0, %0";
2236     case 3:
2237     case 4:
2238       if (get_attr_mode (insn) == MODE_V4SF)
2239         return "movaps\t{%1, %0|%0, %1}";
2240       else
2241         return "movdqa\t{%1, %0|%0, %1}";
2242     default:
2243       gcc_unreachable ();
2244     }
2246   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2247    (set (attr "mode")
2248         (cond [(eq_attr "alternative" "2,3")
2249                  (if_then_else
2250                    (ne (symbol_ref "optimize_size")
2251                        (const_int 0))
2252                    (const_string "V4SF")
2253                    (const_string "TI"))
2254                (eq_attr "alternative" "4")
2255                  (if_then_else
2256                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2257                             (const_int 0))
2258                         (ne (symbol_ref "optimize_size")
2259                             (const_int 0)))
2260                    (const_string "V4SF")
2261                    (const_string "TI"))]
2262                (const_string "DI")))])
2264 (define_split
2265   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2266         (match_operand:TI 1 "general_operand" ""))]
2267   "reload_completed && !SSE_REG_P (operands[0])
2268    && !SSE_REG_P (operands[1])"
2269   [(const_int 0)]
2270   "ix86_split_long_move (operands); DONE;")
2272 ;; This expands to what emit_move_complex would generate if we didn't
2273 ;; have a movti pattern.  Having this avoids problems with reload on
2274 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2275 ;; to have around all the time.
2276 (define_expand "movcdi"
2277   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2278         (match_operand:CDI 1 "general_operand" ""))]
2279   ""
2281   if (push_operand (operands[0], CDImode))
2282     emit_move_complex_push (CDImode, operands[0], operands[1]);
2283   else
2284     emit_move_complex_parts (operands[0], operands[1]);
2285   DONE;
2288 (define_expand "movsf"
2289   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2290         (match_operand:SF 1 "general_operand" ""))]
2291   ""
2292   "ix86_expand_move (SFmode, operands); DONE;")
2294 (define_insn "*pushsf"
2295   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2296         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2297   "!TARGET_64BIT"
2299   /* Anything else should be already split before reg-stack.  */
2300   gcc_assert (which_alternative == 1);
2301   return "push{l}\t%1";
2303   [(set_attr "type" "multi,push,multi")
2304    (set_attr "unit" "i387,*,*")
2305    (set_attr "mode" "SF,SI,SF")])
2307 (define_insn "*pushsf_rex64"
2308   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2309         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2310   "TARGET_64BIT"
2312   /* Anything else should be already split before reg-stack.  */
2313   gcc_assert (which_alternative == 1);
2314   return "push{q}\t%q1";
2316   [(set_attr "type" "multi,push,multi")
2317    (set_attr "unit" "i387,*,*")
2318    (set_attr "mode" "SF,DI,SF")])
2320 (define_split
2321   [(set (match_operand:SF 0 "push_operand" "")
2322         (match_operand:SF 1 "memory_operand" ""))]
2323   "reload_completed
2324    && MEM_P (operands[1])
2325    && (operands[2] = find_constant_src (insn))"
2326   [(set (match_dup 0)
2327         (match_dup 2))])
2330 ;; %%% Kill this when call knows how to work this out.
2331 (define_split
2332   [(set (match_operand:SF 0 "push_operand" "")
2333         (match_operand:SF 1 "any_fp_register_operand" ""))]
2334   "!TARGET_64BIT"
2335   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2336    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2338 (define_split
2339   [(set (match_operand:SF 0 "push_operand" "")
2340         (match_operand:SF 1 "any_fp_register_operand" ""))]
2341   "TARGET_64BIT"
2342   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2343    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2345 (define_insn "*movsf_1"
2346   [(set (match_operand:SF 0 "nonimmediate_operand"
2347           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2348         (match_operand:SF 1 "general_operand"
2349           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2350   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2351    && (reload_in_progress || reload_completed
2352        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2353        || (!TARGET_SSE_MATH && optimize_size
2354            && standard_80387_constant_p (operands[1]))
2355        || GET_CODE (operands[1]) != CONST_DOUBLE
2356        || memory_operand (operands[0], SFmode))"
2358   switch (which_alternative)
2359     {
2360     case 0:
2361     case 1:
2362       return output_387_reg_move (insn, operands);
2364     case 2:
2365       return standard_80387_constant_opcode (operands[1]);
2367     case 3:
2368     case 4:
2369       return "mov{l}\t{%1, %0|%0, %1}";
2370     case 5:
2371       if (get_attr_mode (insn) == MODE_TI)
2372         return "pxor\t%0, %0";
2373       else
2374         return "xorps\t%0, %0";
2375     case 6:
2376       if (get_attr_mode (insn) == MODE_V4SF)
2377         return "movaps\t{%1, %0|%0, %1}";
2378       else
2379         return "movss\t{%1, %0|%0, %1}";
2380     case 7: case 8:
2381       return "movss\t{%1, %0|%0, %1}";
2383     case 9: case 10:
2384     case 12: case 13: case 14: case 15:
2385       return "movd\t{%1, %0|%0, %1}";
2387     case 11:
2388       return "movq\t{%1, %0|%0, %1}";
2390     default:
2391       gcc_unreachable ();
2392     }
2394   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2395    (set (attr "mode")
2396         (cond [(eq_attr "alternative" "3,4,9,10")
2397                  (const_string "SI")
2398                (eq_attr "alternative" "5")
2399                  (if_then_else
2400                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2401                                  (const_int 0))
2402                              (ne (symbol_ref "TARGET_SSE2")
2403                                  (const_int 0)))
2404                         (eq (symbol_ref "optimize_size")
2405                             (const_int 0)))
2406                    (const_string "TI")
2407                    (const_string "V4SF"))
2408                /* For architectures resolving dependencies on
2409                   whole SSE registers use APS move to break dependency
2410                   chains, otherwise use short move to avoid extra work.
2412                   Do the same for architectures resolving dependencies on
2413                   the parts.  While in DF mode it is better to always handle
2414                   just register parts, the SF mode is different due to lack
2415                   of instructions to load just part of the register.  It is
2416                   better to maintain the whole registers in single format
2417                   to avoid problems on using packed logical operations.  */
2418                (eq_attr "alternative" "6")
2419                  (if_then_else
2420                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2421                             (const_int 0))
2422                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2423                             (const_int 0)))
2424                    (const_string "V4SF")
2425                    (const_string "SF"))
2426                (eq_attr "alternative" "11")
2427                  (const_string "DI")]
2428                (const_string "SF")))])
2430 (define_insn "*swapsf"
2431   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2432         (match_operand:SF 1 "fp_register_operand" "+f"))
2433    (set (match_dup 1)
2434         (match_dup 0))]
2435   "reload_completed || TARGET_80387"
2437   if (STACK_TOP_P (operands[0]))
2438     return "fxch\t%1";
2439   else
2440     return "fxch\t%0";
2442   [(set_attr "type" "fxch")
2443    (set_attr "mode" "SF")])
2445 (define_expand "movdf"
2446   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2447         (match_operand:DF 1 "general_operand" ""))]
2448   ""
2449   "ix86_expand_move (DFmode, operands); DONE;")
2451 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2452 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2453 ;; On the average, pushdf using integers can be still shorter.  Allow this
2454 ;; pattern for optimize_size too.
2456 (define_insn "*pushdf_nointeger"
2457   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2458         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2459   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2461   /* This insn should be already split before reg-stack.  */
2462   gcc_unreachable ();
2464   [(set_attr "type" "multi")
2465    (set_attr "unit" "i387,*,*,*")
2466    (set_attr "mode" "DF,SI,SI,DF")])
2468 (define_insn "*pushdf_integer"
2469   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2470         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2471   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2473   /* This insn should be already split before reg-stack.  */
2474   gcc_unreachable ();
2476   [(set_attr "type" "multi")
2477    (set_attr "unit" "i387,*,*")
2478    (set_attr "mode" "DF,SI,DF")])
2480 ;; %%% Kill this when call knows how to work this out.
2481 (define_split
2482   [(set (match_operand:DF 0 "push_operand" "")
2483         (match_operand:DF 1 "any_fp_register_operand" ""))]
2484   "!TARGET_64BIT && reload_completed"
2485   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2486    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2487   "")
2489 (define_split
2490   [(set (match_operand:DF 0 "push_operand" "")
2491         (match_operand:DF 1 "any_fp_register_operand" ""))]
2492   "TARGET_64BIT && reload_completed"
2493   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2494    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2495   "")
2497 (define_split
2498   [(set (match_operand:DF 0 "push_operand" "")
2499         (match_operand:DF 1 "general_operand" ""))]
2500   "reload_completed"
2501   [(const_int 0)]
2502   "ix86_split_long_move (operands); DONE;")
2504 ;; Moving is usually shorter when only FP registers are used. This separate
2505 ;; movdf pattern avoids the use of integer registers for FP operations
2506 ;; when optimizing for size.
2508 (define_insn "*movdf_nointeger"
2509   [(set (match_operand:DF 0 "nonimmediate_operand"
2510                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2511         (match_operand:DF 1 "general_operand"
2512                         "fm,f,G,*roF,F*r,C   ,Y2*x,mY2*x,Y2*x"))]
2513   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2514    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2515    && (reload_in_progress || reload_completed
2516        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2517        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2518            && standard_80387_constant_p (operands[1]))
2519        || GET_CODE (operands[1]) != CONST_DOUBLE
2520        || memory_operand (operands[0], DFmode))"
2522   switch (which_alternative)
2523     {
2524     case 0:
2525     case 1:
2526       return output_387_reg_move (insn, operands);
2528     case 2:
2529       return standard_80387_constant_opcode (operands[1]);
2531     case 3:
2532     case 4:
2533       return "#";
2534     case 5:
2535       switch (get_attr_mode (insn))
2536         {
2537         case MODE_V4SF:
2538           return "xorps\t%0, %0";
2539         case MODE_V2DF:
2540           return "xorpd\t%0, %0";
2541         case MODE_TI:
2542           return "pxor\t%0, %0";
2543         default:
2544           gcc_unreachable ();
2545         }
2546     case 6:
2547     case 7:
2548     case 8:
2549       switch (get_attr_mode (insn))
2550         {
2551         case MODE_V4SF:
2552           return "movaps\t{%1, %0|%0, %1}";
2553         case MODE_V2DF:
2554           return "movapd\t{%1, %0|%0, %1}";
2555         case MODE_TI:
2556           return "movdqa\t{%1, %0|%0, %1}";
2557         case MODE_DI:
2558           return "movq\t{%1, %0|%0, %1}";
2559         case MODE_DF:
2560           return "movsd\t{%1, %0|%0, %1}";
2561         case MODE_V1DF:
2562           return "movlpd\t{%1, %0|%0, %1}";
2563         case MODE_V2SF:
2564           return "movlps\t{%1, %0|%0, %1}";
2565         default:
2566           gcc_unreachable ();
2567         }
2569     default:
2570       gcc_unreachable ();
2571     }
2573   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2574    (set (attr "mode")
2575         (cond [(eq_attr "alternative" "0,1,2")
2576                  (const_string "DF")
2577                (eq_attr "alternative" "3,4")
2578                  (const_string "SI")
2580                /* For SSE1, we have many fewer alternatives.  */
2581                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2582                  (cond [(eq_attr "alternative" "5,6")
2583                           (const_string "V4SF")
2584                        ]
2585                    (const_string "V2SF"))
2587                /* xorps is one byte shorter.  */
2588                (eq_attr "alternative" "5")
2589                  (cond [(ne (symbol_ref "optimize_size")
2590                             (const_int 0))
2591                           (const_string "V4SF")
2592                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2593                             (const_int 0))
2594                           (const_string "TI")
2595                        ]
2596                        (const_string "V2DF"))
2598                /* For architectures resolving dependencies on
2599                   whole SSE registers use APD move to break dependency
2600                   chains, otherwise use short move to avoid extra work.
2602                   movaps encodes one byte shorter.  */
2603                (eq_attr "alternative" "6")
2604                  (cond
2605                    [(ne (symbol_ref "optimize_size")
2606                         (const_int 0))
2607                       (const_string "V4SF")
2608                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2609                         (const_int 0))
2610                       (const_string "V2DF")
2611                    ]
2612                    (const_string "DF"))
2613                /* For architectures resolving dependencies on register
2614                   parts we may avoid extra work to zero out upper part
2615                   of register.  */
2616                (eq_attr "alternative" "7")
2617                  (if_then_else
2618                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2619                        (const_int 0))
2620                    (const_string "V1DF")
2621                    (const_string "DF"))
2622               ]
2623               (const_string "DF")))])
2625 (define_insn "*movdf_integer_rex64"
2626   [(set (match_operand:DF 0 "nonimmediate_operand"
2627                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2628         (match_operand:DF 1 "general_operand"
2629                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2630   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2631    && (reload_in_progress || reload_completed
2632        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2633        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2634            && standard_80387_constant_p (operands[1]))
2635        || GET_CODE (operands[1]) != CONST_DOUBLE
2636        || memory_operand (operands[0], DFmode))"
2638   switch (which_alternative)
2639     {
2640     case 0:
2641     case 1:
2642       return output_387_reg_move (insn, operands);
2644     case 2:
2645       return standard_80387_constant_opcode (operands[1]);
2647     case 3:
2648     case 4:
2649       return "#";
2651     case 5:
2652       switch (get_attr_mode (insn))
2653         {
2654         case MODE_V4SF:
2655           return "xorps\t%0, %0";
2656         case MODE_V2DF:
2657           return "xorpd\t%0, %0";
2658         case MODE_TI:
2659           return "pxor\t%0, %0";
2660         default:
2661           gcc_unreachable ();
2662         }
2663     case 6:
2664     case 7:
2665     case 8:
2666       switch (get_attr_mode (insn))
2667         {
2668         case MODE_V4SF:
2669           return "movaps\t{%1, %0|%0, %1}";
2670         case MODE_V2DF:
2671           return "movapd\t{%1, %0|%0, %1}";
2672         case MODE_TI:
2673           return "movdqa\t{%1, %0|%0, %1}";
2674         case MODE_DI:
2675           return "movq\t{%1, %0|%0, %1}";
2676         case MODE_DF:
2677           return "movsd\t{%1, %0|%0, %1}";
2678         case MODE_V1DF:
2679           return "movlpd\t{%1, %0|%0, %1}";
2680         case MODE_V2SF:
2681           return "movlps\t{%1, %0|%0, %1}";
2682         default:
2683           gcc_unreachable ();
2684         }
2686     case 9:
2687     case 10:
2688       return "movd\t{%1, %0|%0, %1}";
2690     default:
2691       gcc_unreachable();
2692     }
2694   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2695    (set (attr "mode")
2696         (cond [(eq_attr "alternative" "0,1,2")
2697                  (const_string "DF")
2698                (eq_attr "alternative" "3,4,9,10")
2699                  (const_string "DI")
2701                /* For SSE1, we have many fewer alternatives.  */
2702                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2703                  (cond [(eq_attr "alternative" "5,6")
2704                           (const_string "V4SF")
2705                        ]
2706                    (const_string "V2SF"))
2708                /* xorps is one byte shorter.  */
2709                (eq_attr "alternative" "5")
2710                  (cond [(ne (symbol_ref "optimize_size")
2711                             (const_int 0))
2712                           (const_string "V4SF")
2713                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2714                             (const_int 0))
2715                           (const_string "TI")
2716                        ]
2717                        (const_string "V2DF"))
2719                /* For architectures resolving dependencies on
2720                   whole SSE registers use APD move to break dependency
2721                   chains, otherwise use short move to avoid extra work.
2723                   movaps encodes one byte shorter.  */
2724                (eq_attr "alternative" "6")
2725                  (cond
2726                    [(ne (symbol_ref "optimize_size")
2727                         (const_int 0))
2728                       (const_string "V4SF")
2729                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2730                         (const_int 0))
2731                       (const_string "V2DF")
2732                    ]
2733                    (const_string "DF"))
2734                /* For architectures resolving dependencies on register
2735                   parts we may avoid extra work to zero out upper part
2736                   of register.  */
2737                (eq_attr "alternative" "7")
2738                  (if_then_else
2739                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2740                        (const_int 0))
2741                    (const_string "V1DF")
2742                    (const_string "DF"))
2743               ]
2744               (const_string "DF")))])
2746 (define_insn "*movdf_integer"
2747   [(set (match_operand:DF 0 "nonimmediate_operand"
2748                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2749         (match_operand:DF 1 "general_operand"
2750                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2751   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2752    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2753    && (reload_in_progress || reload_completed
2754        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2755        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2756            && standard_80387_constant_p (operands[1]))
2757        || GET_CODE (operands[1]) != CONST_DOUBLE
2758        || memory_operand (operands[0], DFmode))"
2760   switch (which_alternative)
2761     {
2762     case 0:
2763     case 1:
2764       return output_387_reg_move (insn, operands);
2766     case 2:
2767       return standard_80387_constant_opcode (operands[1]);
2769     case 3:
2770     case 4:
2771       return "#";
2773     case 5:
2774       switch (get_attr_mode (insn))
2775         {
2776         case MODE_V4SF:
2777           return "xorps\t%0, %0";
2778         case MODE_V2DF:
2779           return "xorpd\t%0, %0";
2780         case MODE_TI:
2781           return "pxor\t%0, %0";
2782         default:
2783           gcc_unreachable ();
2784         }
2785     case 6:
2786     case 7:
2787     case 8:
2788       switch (get_attr_mode (insn))
2789         {
2790         case MODE_V4SF:
2791           return "movaps\t{%1, %0|%0, %1}";
2792         case MODE_V2DF:
2793           return "movapd\t{%1, %0|%0, %1}";
2794         case MODE_TI:
2795           return "movdqa\t{%1, %0|%0, %1}";
2796         case MODE_DI:
2797           return "movq\t{%1, %0|%0, %1}";
2798         case MODE_DF:
2799           return "movsd\t{%1, %0|%0, %1}";
2800         case MODE_V1DF:
2801           return "movlpd\t{%1, %0|%0, %1}";
2802         case MODE_V2SF:
2803           return "movlps\t{%1, %0|%0, %1}";
2804         default:
2805           gcc_unreachable ();
2806         }
2808     default:
2809       gcc_unreachable();
2810     }
2812   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2813    (set (attr "mode")
2814         (cond [(eq_attr "alternative" "0,1,2")
2815                  (const_string "DF")
2816                (eq_attr "alternative" "3,4")
2817                  (const_string "SI")
2819                /* For SSE1, we have many fewer alternatives.  */
2820                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2821                  (cond [(eq_attr "alternative" "5,6")
2822                           (const_string "V4SF")
2823                        ]
2824                    (const_string "V2SF"))
2826                /* xorps is one byte shorter.  */
2827                (eq_attr "alternative" "5")
2828                  (cond [(ne (symbol_ref "optimize_size")
2829                             (const_int 0))
2830                           (const_string "V4SF")
2831                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2832                             (const_int 0))
2833                           (const_string "TI")
2834                        ]
2835                        (const_string "V2DF"))
2837                /* For architectures resolving dependencies on
2838                   whole SSE registers use APD move to break dependency
2839                   chains, otherwise use short move to avoid extra work.
2841                   movaps encodes one byte shorter.  */
2842                (eq_attr "alternative" "6")
2843                  (cond
2844                    [(ne (symbol_ref "optimize_size")
2845                         (const_int 0))
2846                       (const_string "V4SF")
2847                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2848                         (const_int 0))
2849                       (const_string "V2DF")
2850                    ]
2851                    (const_string "DF"))
2852                /* For architectures resolving dependencies on register
2853                   parts we may avoid extra work to zero out upper part
2854                   of register.  */
2855                (eq_attr "alternative" "7")
2856                  (if_then_else
2857                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2858                        (const_int 0))
2859                    (const_string "V1DF")
2860                    (const_string "DF"))
2861               ]
2862               (const_string "DF")))])
2864 (define_split
2865   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2866         (match_operand:DF 1 "general_operand" ""))]
2867   "reload_completed
2868    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2869    && ! (ANY_FP_REG_P (operands[0]) ||
2870          (GET_CODE (operands[0]) == SUBREG
2871           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2872    && ! (ANY_FP_REG_P (operands[1]) ||
2873          (GET_CODE (operands[1]) == SUBREG
2874           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2875   [(const_int 0)]
2876   "ix86_split_long_move (operands); DONE;")
2878 (define_insn "*swapdf"
2879   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2880         (match_operand:DF 1 "fp_register_operand" "+f"))
2881    (set (match_dup 1)
2882         (match_dup 0))]
2883   "reload_completed || TARGET_80387"
2885   if (STACK_TOP_P (operands[0]))
2886     return "fxch\t%1";
2887   else
2888     return "fxch\t%0";
2890   [(set_attr "type" "fxch")
2891    (set_attr "mode" "DF")])
2893 (define_expand "movxf"
2894   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2895         (match_operand:XF 1 "general_operand" ""))]
2896   ""
2897   "ix86_expand_move (XFmode, operands); DONE;")
2899 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2900 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2901 ;; Pushing using integer instructions is longer except for constants
2902 ;; and direct memory references.
2903 ;; (assuming that any given constant is pushed only once, but this ought to be
2904 ;;  handled elsewhere).
2906 (define_insn "*pushxf_nointeger"
2907   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2908         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2909   "optimize_size"
2911   /* This insn should be already split before reg-stack.  */
2912   gcc_unreachable ();
2914   [(set_attr "type" "multi")
2915    (set_attr "unit" "i387,*,*")
2916    (set_attr "mode" "XF,SI,SI")])
2918 (define_insn "*pushxf_integer"
2919   [(set (match_operand:XF 0 "push_operand" "=<,<")
2920         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2921   "!optimize_size"
2923   /* This insn should be already split before reg-stack.  */
2924   gcc_unreachable ();
2926   [(set_attr "type" "multi")
2927    (set_attr "unit" "i387,*")
2928    (set_attr "mode" "XF,SI")])
2930 (define_split
2931   [(set (match_operand 0 "push_operand" "")
2932         (match_operand 1 "general_operand" ""))]
2933   "reload_completed
2934    && (GET_MODE (operands[0]) == XFmode
2935        || GET_MODE (operands[0]) == DFmode)
2936    && !ANY_FP_REG_P (operands[1])"
2937   [(const_int 0)]
2938   "ix86_split_long_move (operands); DONE;")
2940 (define_split
2941   [(set (match_operand:XF 0 "push_operand" "")
2942         (match_operand:XF 1 "any_fp_register_operand" ""))]
2943   "!TARGET_64BIT"
2944   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2945    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2946   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2948 (define_split
2949   [(set (match_operand:XF 0 "push_operand" "")
2950         (match_operand:XF 1 "any_fp_register_operand" ""))]
2951   "TARGET_64BIT"
2952   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2953    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2954   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2956 ;; Do not use integer registers when optimizing for size
2957 (define_insn "*movxf_nointeger"
2958   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2959         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2960   "optimize_size
2961    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2962    && (reload_in_progress || reload_completed
2963        || (optimize_size && standard_80387_constant_p (operands[1]))
2964        || GET_CODE (operands[1]) != CONST_DOUBLE
2965        || memory_operand (operands[0], XFmode))"
2967   switch (which_alternative)
2968     {
2969     case 0:
2970     case 1:
2971       return output_387_reg_move (insn, operands);
2973     case 2:
2974       return standard_80387_constant_opcode (operands[1]);
2976     case 3: case 4:
2977       return "#";
2978     default:
2979       gcc_unreachable ();
2980     }
2982   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2983    (set_attr "mode" "XF,XF,XF,SI,SI")])
2985 (define_insn "*movxf_integer"
2986   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2987         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2988   "!optimize_size
2989    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2990    && (reload_in_progress || reload_completed
2991        || (optimize_size && standard_80387_constant_p (operands[1]))
2992        || GET_CODE (operands[1]) != CONST_DOUBLE
2993        || memory_operand (operands[0], XFmode))"
2995   switch (which_alternative)
2996     {
2997     case 0:
2998     case 1:
2999       return output_387_reg_move (insn, operands);
3001     case 2:
3002       return standard_80387_constant_opcode (operands[1]);
3004     case 3: case 4:
3005       return "#";
3007     default:
3008       gcc_unreachable ();
3009     }
3011   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3012    (set_attr "mode" "XF,XF,XF,SI,SI")])
3014 (define_split
3015   [(set (match_operand 0 "nonimmediate_operand" "")
3016         (match_operand 1 "general_operand" ""))]
3017   "reload_completed
3018    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3019    && GET_MODE (operands[0]) == XFmode
3020    && ! (ANY_FP_REG_P (operands[0]) ||
3021          (GET_CODE (operands[0]) == SUBREG
3022           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3023    && ! (ANY_FP_REG_P (operands[1]) ||
3024          (GET_CODE (operands[1]) == SUBREG
3025           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3026   [(const_int 0)]
3027   "ix86_split_long_move (operands); DONE;")
3029 (define_split
3030   [(set (match_operand 0 "register_operand" "")
3031         (match_operand 1 "memory_operand" ""))]
3032   "reload_completed
3033    && MEM_P (operands[1])
3034    && (GET_MODE (operands[0]) == XFmode
3035        || GET_MODE (operands[0]) == SFmode
3036        || GET_MODE (operands[0]) == DFmode)
3037    && (operands[2] = find_constant_src (insn))"
3038   [(set (match_dup 0) (match_dup 2))]
3040   rtx c = operands[2];
3041   rtx r = operands[0];
3043   if (GET_CODE (r) == SUBREG)
3044     r = SUBREG_REG (r);
3046   if (SSE_REG_P (r))
3047     {
3048       if (!standard_sse_constant_p (c))
3049         FAIL;
3050     }
3051   else if (FP_REG_P (r))
3052     {
3053       if (!standard_80387_constant_p (c))
3054         FAIL;
3055     }
3056   else if (MMX_REG_P (r))
3057     FAIL;
3060 (define_split
3061   [(set (match_operand 0 "register_operand" "")
3062         (float_extend (match_operand 1 "memory_operand" "")))]
3063   "reload_completed
3064    && MEM_P (operands[1])
3065    && (GET_MODE (operands[0]) == XFmode
3066        || GET_MODE (operands[0]) == SFmode
3067        || GET_MODE (operands[0]) == DFmode)
3068    && (operands[2] = find_constant_src (insn))"
3069   [(set (match_dup 0) (match_dup 2))]
3071   rtx c = operands[2];
3072   rtx r = operands[0];
3074   if (GET_CODE (r) == SUBREG)
3075     r = SUBREG_REG (r);
3077   if (SSE_REG_P (r))
3078     {
3079       if (!standard_sse_constant_p (c))
3080         FAIL;
3081     }
3082   else if (FP_REG_P (r))
3083     {
3084       if (!standard_80387_constant_p (c))
3085         FAIL;
3086     }
3087   else if (MMX_REG_P (r))
3088     FAIL;
3091 (define_insn "swapxf"
3092   [(set (match_operand:XF 0 "register_operand" "+f")
3093         (match_operand:XF 1 "register_operand" "+f"))
3094    (set (match_dup 1)
3095         (match_dup 0))]
3096   "TARGET_80387"
3098   if (STACK_TOP_P (operands[0]))
3099     return "fxch\t%1";
3100   else
3101     return "fxch\t%0";
3103   [(set_attr "type" "fxch")
3104    (set_attr "mode" "XF")])
3106 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3107 (define_split
3108   [(set (match_operand:X87MODEF 0 "register_operand" "")
3109         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3110   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3111    && (standard_80387_constant_p (operands[1]) == 8
3112        || standard_80387_constant_p (operands[1]) == 9)"
3113   [(set (match_dup 0)(match_dup 1))
3114    (set (match_dup 0)
3115         (neg:X87MODEF (match_dup 0)))]
3117   REAL_VALUE_TYPE r;
3119   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3120   if (real_isnegzero (&r))
3121     operands[1] = CONST0_RTX (<MODE>mode);
3122   else
3123     operands[1] = CONST1_RTX (<MODE>mode);
3126 (define_expand "movtf"
3127   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3128         (match_operand:TF 1 "nonimmediate_operand" ""))]
3129   "TARGET_64BIT"
3131   ix86_expand_move (TFmode, operands);
3132   DONE;
3135 (define_insn "*movtf_internal"
3136   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3137         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3138   "TARGET_64BIT
3139    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3141   switch (which_alternative)
3142     {
3143     case 0:
3144     case 1:
3145       return "#";
3146     case 2:
3147       if (get_attr_mode (insn) == MODE_V4SF)
3148         return "xorps\t%0, %0";
3149       else
3150         return "pxor\t%0, %0";
3151     case 3:
3152     case 4:
3153       if (get_attr_mode (insn) == MODE_V4SF)
3154         return "movaps\t{%1, %0|%0, %1}";
3155       else
3156         return "movdqa\t{%1, %0|%0, %1}";
3157     default:
3158       gcc_unreachable ();
3159     }
3161   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3162    (set (attr "mode")
3163         (cond [(eq_attr "alternative" "2,3")
3164                  (if_then_else
3165                    (ne (symbol_ref "optimize_size")
3166                        (const_int 0))
3167                    (const_string "V4SF")
3168                    (const_string "TI"))
3169                (eq_attr "alternative" "4")
3170                  (if_then_else
3171                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3172                             (const_int 0))
3173                         (ne (symbol_ref "optimize_size")
3174                             (const_int 0)))
3175                    (const_string "V4SF")
3176                    (const_string "TI"))]
3177                (const_string "DI")))])
3179 (define_split
3180   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3181         (match_operand:TF 1 "general_operand" ""))]
3182   "reload_completed && !SSE_REG_P (operands[0])
3183    && !SSE_REG_P (operands[1])"
3184   [(const_int 0)]
3185   "ix86_split_long_move (operands); DONE;")
3187 ;; Zero extension instructions
3189 (define_expand "zero_extendhisi2"
3190   [(set (match_operand:SI 0 "register_operand" "")
3191      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3192   ""
3194   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3195     {
3196       operands[1] = force_reg (HImode, operands[1]);
3197       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3198       DONE;
3199     }
3202 (define_insn "zero_extendhisi2_and"
3203   [(set (match_operand:SI 0 "register_operand" "=r")
3204      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3205    (clobber (reg:CC FLAGS_REG))]
3206   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3207   "#"
3208   [(set_attr "type" "alu1")
3209    (set_attr "mode" "SI")])
3211 (define_split
3212   [(set (match_operand:SI 0 "register_operand" "")
3213         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3214    (clobber (reg:CC FLAGS_REG))]
3215   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3216   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3217               (clobber (reg:CC FLAGS_REG))])]
3218   "")
3220 (define_insn "*zero_extendhisi2_movzwl"
3221   [(set (match_operand:SI 0 "register_operand" "=r")
3222      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3223   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3224   "movz{wl|x}\t{%1, %0|%0, %1}"
3225   [(set_attr "type" "imovx")
3226    (set_attr "mode" "SI")])
3228 (define_expand "zero_extendqihi2"
3229   [(parallel
3230     [(set (match_operand:HI 0 "register_operand" "")
3231        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3232      (clobber (reg:CC FLAGS_REG))])]
3233   ""
3234   "")
3236 (define_insn "*zero_extendqihi2_and"
3237   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3238      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3239    (clobber (reg:CC FLAGS_REG))]
3240   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3241   "#"
3242   [(set_attr "type" "alu1")
3243    (set_attr "mode" "HI")])
3245 (define_insn "*zero_extendqihi2_movzbw_and"
3246   [(set (match_operand:HI 0 "register_operand" "=r,r")
3247      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3248    (clobber (reg:CC FLAGS_REG))]
3249   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3250   "#"
3251   [(set_attr "type" "imovx,alu1")
3252    (set_attr "mode" "HI")])
3254 ; zero extend to SImode here to avoid partial register stalls
3255 (define_insn "*zero_extendqihi2_movzbl"
3256   [(set (match_operand:HI 0 "register_operand" "=r")
3257      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3258   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3259   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3260   [(set_attr "type" "imovx")
3261    (set_attr "mode" "SI")])
3263 ;; For the movzbw case strip only the clobber
3264 (define_split
3265   [(set (match_operand:HI 0 "register_operand" "")
3266         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3267    (clobber (reg:CC FLAGS_REG))]
3268   "reload_completed
3269    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3270    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3271   [(set (match_operand:HI 0 "register_operand" "")
3272         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3274 ;; When source and destination does not overlap, clear destination
3275 ;; first and then do the movb
3276 (define_split
3277   [(set (match_operand:HI 0 "register_operand" "")
3278         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3279    (clobber (reg:CC FLAGS_REG))]
3280   "reload_completed
3281    && ANY_QI_REG_P (operands[0])
3282    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3283    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3284   [(set (match_dup 0) (const_int 0))
3285    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3286   "operands[2] = gen_lowpart (QImode, operands[0]);")
3288 ;; Rest is handled by single and.
3289 (define_split
3290   [(set (match_operand:HI 0 "register_operand" "")
3291         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3292    (clobber (reg:CC FLAGS_REG))]
3293   "reload_completed
3294    && true_regnum (operands[0]) == true_regnum (operands[1])"
3295   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3296               (clobber (reg:CC FLAGS_REG))])]
3297   "")
3299 (define_expand "zero_extendqisi2"
3300   [(parallel
3301     [(set (match_operand:SI 0 "register_operand" "")
3302        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3303      (clobber (reg:CC FLAGS_REG))])]
3304   ""
3305   "")
3307 (define_insn "*zero_extendqisi2_and"
3308   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3309      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3310    (clobber (reg:CC FLAGS_REG))]
3311   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3312   "#"
3313   [(set_attr "type" "alu1")
3314    (set_attr "mode" "SI")])
3316 (define_insn "*zero_extendqisi2_movzbw_and"
3317   [(set (match_operand:SI 0 "register_operand" "=r,r")
3318      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3319    (clobber (reg:CC FLAGS_REG))]
3320   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3321   "#"
3322   [(set_attr "type" "imovx,alu1")
3323    (set_attr "mode" "SI")])
3325 (define_insn "*zero_extendqisi2_movzbw"
3326   [(set (match_operand:SI 0 "register_operand" "=r")
3327      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3328   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3329   "movz{bl|x}\t{%1, %0|%0, %1}"
3330   [(set_attr "type" "imovx")
3331    (set_attr "mode" "SI")])
3333 ;; For the movzbl case strip only the clobber
3334 (define_split
3335   [(set (match_operand:SI 0 "register_operand" "")
3336         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3337    (clobber (reg:CC FLAGS_REG))]
3338   "reload_completed
3339    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3340    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3341   [(set (match_dup 0)
3342         (zero_extend:SI (match_dup 1)))])
3344 ;; When source and destination does not overlap, clear destination
3345 ;; first and then do the movb
3346 (define_split
3347   [(set (match_operand:SI 0 "register_operand" "")
3348         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3349    (clobber (reg:CC FLAGS_REG))]
3350   "reload_completed
3351    && ANY_QI_REG_P (operands[0])
3352    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3353    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3354    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3355   [(set (match_dup 0) (const_int 0))
3356    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3357   "operands[2] = gen_lowpart (QImode, operands[0]);")
3359 ;; Rest is handled by single and.
3360 (define_split
3361   [(set (match_operand:SI 0 "register_operand" "")
3362         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3363    (clobber (reg:CC FLAGS_REG))]
3364   "reload_completed
3365    && true_regnum (operands[0]) == true_regnum (operands[1])"
3366   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3367               (clobber (reg:CC FLAGS_REG))])]
3368   "")
3370 ;; %%% Kill me once multi-word ops are sane.
3371 (define_expand "zero_extendsidi2"
3372   [(set (match_operand:DI 0 "register_operand" "=r")
3373      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3374   ""
3376   if (!TARGET_64BIT)
3377     {
3378       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3379       DONE;
3380     }
3383 (define_insn "zero_extendsidi2_32"
3384   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3385         (zero_extend:DI
3386          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3387    (clobber (reg:CC FLAGS_REG))]
3388   "!TARGET_64BIT"
3389   "@
3390    #
3391    #
3392    #
3393    movd\t{%1, %0|%0, %1}
3394    movd\t{%1, %0|%0, %1}
3395    movd\t{%1, %0|%0, %1}
3396    movd\t{%1, %0|%0, %1}"
3397   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3398    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3400 (define_insn "zero_extendsidi2_rex64"
3401   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3402      (zero_extend:DI
3403        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3404   "TARGET_64BIT"
3405   "@
3406    mov\t{%k1, %k0|%k0, %k1}
3407    #
3408    movd\t{%1, %0|%0, %1}
3409    movd\t{%1, %0|%0, %1}
3410    movd\t{%1, %0|%0, %1}
3411    movd\t{%1, %0|%0, %1}"
3412   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3413    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3415 (define_split
3416   [(set (match_operand:DI 0 "memory_operand" "")
3417      (zero_extend:DI (match_dup 0)))]
3418   "TARGET_64BIT"
3419   [(set (match_dup 4) (const_int 0))]
3420   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3422 (define_split
3423   [(set (match_operand:DI 0 "register_operand" "")
3424         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3425    (clobber (reg:CC FLAGS_REG))]
3426   "!TARGET_64BIT && reload_completed
3427    && true_regnum (operands[0]) == true_regnum (operands[1])"
3428   [(set (match_dup 4) (const_int 0))]
3429   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3431 (define_split
3432   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3433         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3434    (clobber (reg:CC FLAGS_REG))]
3435   "!TARGET_64BIT && reload_completed
3436    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3437   [(set (match_dup 3) (match_dup 1))
3438    (set (match_dup 4) (const_int 0))]
3439   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3441 (define_insn "zero_extendhidi2"
3442   [(set (match_operand:DI 0 "register_operand" "=r")
3443      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3444   "TARGET_64BIT"
3445   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3446   [(set_attr "type" "imovx")
3447    (set_attr "mode" "DI")])
3449 (define_insn "zero_extendqidi2"
3450   [(set (match_operand:DI 0 "register_operand" "=r")
3451      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3452   "TARGET_64BIT"
3453   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3454   [(set_attr "type" "imovx")
3455    (set_attr "mode" "DI")])
3457 ;; Sign extension instructions
3459 (define_expand "extendsidi2"
3460   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3461                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3462               (clobber (reg:CC FLAGS_REG))
3463               (clobber (match_scratch:SI 2 ""))])]
3464   ""
3466   if (TARGET_64BIT)
3467     {
3468       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3469       DONE;
3470     }
3473 (define_insn "*extendsidi2_1"
3474   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3475         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3476    (clobber (reg:CC FLAGS_REG))
3477    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3478   "!TARGET_64BIT"
3479   "#")
3481 (define_insn "extendsidi2_rex64"
3482   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3483         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3484   "TARGET_64BIT"
3485   "@
3486    {cltq|cdqe}
3487    movs{lq|x}\t{%1,%0|%0, %1}"
3488   [(set_attr "type" "imovx")
3489    (set_attr "mode" "DI")
3490    (set_attr "prefix_0f" "0")
3491    (set_attr "modrm" "0,1")])
3493 (define_insn "extendhidi2"
3494   [(set (match_operand:DI 0 "register_operand" "=r")
3495         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3496   "TARGET_64BIT"
3497   "movs{wq|x}\t{%1,%0|%0, %1}"
3498   [(set_attr "type" "imovx")
3499    (set_attr "mode" "DI")])
3501 (define_insn "extendqidi2"
3502   [(set (match_operand:DI 0 "register_operand" "=r")
3503         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3504   "TARGET_64BIT"
3505   "movs{bq|x}\t{%1,%0|%0, %1}"
3506    [(set_attr "type" "imovx")
3507     (set_attr "mode" "DI")])
3509 ;; Extend to memory case when source register does die.
3510 (define_split
3511   [(set (match_operand:DI 0 "memory_operand" "")
3512         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3513    (clobber (reg:CC FLAGS_REG))
3514    (clobber (match_operand:SI 2 "register_operand" ""))]
3515   "(reload_completed
3516     && dead_or_set_p (insn, operands[1])
3517     && !reg_mentioned_p (operands[1], operands[0]))"
3518   [(set (match_dup 3) (match_dup 1))
3519    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3520               (clobber (reg:CC FLAGS_REG))])
3521    (set (match_dup 4) (match_dup 1))]
3522   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3524 ;; Extend to memory case when source register does not die.
3525 (define_split
3526   [(set (match_operand:DI 0 "memory_operand" "")
3527         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3528    (clobber (reg:CC FLAGS_REG))
3529    (clobber (match_operand:SI 2 "register_operand" ""))]
3530   "reload_completed"
3531   [(const_int 0)]
3533   split_di (&operands[0], 1, &operands[3], &operands[4]);
3535   emit_move_insn (operands[3], operands[1]);
3537   /* Generate a cltd if possible and doing so it profitable.  */
3538   if (true_regnum (operands[1]) == 0
3539       && true_regnum (operands[2]) == 1
3540       && (optimize_size || TARGET_USE_CLTD))
3541     {
3542       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3543     }
3544   else
3545     {
3546       emit_move_insn (operands[2], operands[1]);
3547       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3548     }
3549   emit_move_insn (operands[4], operands[2]);
3550   DONE;
3553 ;; Extend to register case.  Optimize case where source and destination
3554 ;; registers match and cases where we can use cltd.
3555 (define_split
3556   [(set (match_operand:DI 0 "register_operand" "")
3557         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3558    (clobber (reg:CC FLAGS_REG))
3559    (clobber (match_scratch:SI 2 ""))]
3560   "reload_completed"
3561   [(const_int 0)]
3563   split_di (&operands[0], 1, &operands[3], &operands[4]);
3565   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3566     emit_move_insn (operands[3], operands[1]);
3568   /* Generate a cltd if possible and doing so it profitable.  */
3569   if (true_regnum (operands[3]) == 0
3570       && (optimize_size || TARGET_USE_CLTD))
3571     {
3572       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3573       DONE;
3574     }
3576   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3577     emit_move_insn (operands[4], operands[1]);
3579   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3580   DONE;
3583 (define_insn "extendhisi2"
3584   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3585         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3586   ""
3588   switch (get_attr_prefix_0f (insn))
3589     {
3590     case 0:
3591       return "{cwtl|cwde}";
3592     default:
3593       return "movs{wl|x}\t{%1,%0|%0, %1}";
3594     }
3596   [(set_attr "type" "imovx")
3597    (set_attr "mode" "SI")
3598    (set (attr "prefix_0f")
3599      ;; movsx is short decodable while cwtl is vector decoded.
3600      (if_then_else (and (eq_attr "cpu" "!k6")
3601                         (eq_attr "alternative" "0"))
3602         (const_string "0")
3603         (const_string "1")))
3604    (set (attr "modrm")
3605      (if_then_else (eq_attr "prefix_0f" "0")
3606         (const_string "0")
3607         (const_string "1")))])
3609 (define_insn "*extendhisi2_zext"
3610   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3611         (zero_extend:DI
3612           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3613   "TARGET_64BIT"
3615   switch (get_attr_prefix_0f (insn))
3616     {
3617     case 0:
3618       return "{cwtl|cwde}";
3619     default:
3620       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3621     }
3623   [(set_attr "type" "imovx")
3624    (set_attr "mode" "SI")
3625    (set (attr "prefix_0f")
3626      ;; movsx is short decodable while cwtl is vector decoded.
3627      (if_then_else (and (eq_attr "cpu" "!k6")
3628                         (eq_attr "alternative" "0"))
3629         (const_string "0")
3630         (const_string "1")))
3631    (set (attr "modrm")
3632      (if_then_else (eq_attr "prefix_0f" "0")
3633         (const_string "0")
3634         (const_string "1")))])
3636 (define_insn "extendqihi2"
3637   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3638         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3639   ""
3641   switch (get_attr_prefix_0f (insn))
3642     {
3643     case 0:
3644       return "{cbtw|cbw}";
3645     default:
3646       return "movs{bw|x}\t{%1,%0|%0, %1}";
3647     }
3649   [(set_attr "type" "imovx")
3650    (set_attr "mode" "HI")
3651    (set (attr "prefix_0f")
3652      ;; movsx is short decodable while cwtl is vector decoded.
3653      (if_then_else (and (eq_attr "cpu" "!k6")
3654                         (eq_attr "alternative" "0"))
3655         (const_string "0")
3656         (const_string "1")))
3657    (set (attr "modrm")
3658      (if_then_else (eq_attr "prefix_0f" "0")
3659         (const_string "0")
3660         (const_string "1")))])
3662 (define_insn "extendqisi2"
3663   [(set (match_operand:SI 0 "register_operand" "=r")
3664         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3665   ""
3666   "movs{bl|x}\t{%1,%0|%0, %1}"
3667    [(set_attr "type" "imovx")
3668     (set_attr "mode" "SI")])
3670 (define_insn "*extendqisi2_zext"
3671   [(set (match_operand:DI 0 "register_operand" "=r")
3672         (zero_extend:DI
3673           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3674   "TARGET_64BIT"
3675   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3676    [(set_attr "type" "imovx")
3677     (set_attr "mode" "SI")])
3679 ;; Conversions between float and double.
3681 ;; These are all no-ops in the model used for the 80387.  So just
3682 ;; emit moves.
3684 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3685 (define_insn "*dummy_extendsfdf2"
3686   [(set (match_operand:DF 0 "push_operand" "=<")
3687         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3688   "0"
3689   "#")
3691 (define_split
3692   [(set (match_operand:DF 0 "push_operand" "")
3693         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3694   "!TARGET_64BIT"
3695   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3696    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3698 (define_split
3699   [(set (match_operand:DF 0 "push_operand" "")
3700         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3701   "TARGET_64BIT"
3702   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3703    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3705 (define_insn "*dummy_extendsfxf2"
3706   [(set (match_operand:XF 0 "push_operand" "=<")
3707         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3708   "0"
3709   "#")
3711 (define_split
3712   [(set (match_operand:XF 0 "push_operand" "")
3713         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3714   ""
3715   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3716    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3717   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3719 (define_split
3720   [(set (match_operand:XF 0 "push_operand" "")
3721         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3722   "TARGET_64BIT"
3723   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3724    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3725   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3727 (define_split
3728   [(set (match_operand:XF 0 "push_operand" "")
3729         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3730   ""
3731   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3732    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3733   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3735 (define_split
3736   [(set (match_operand:XF 0 "push_operand" "")
3737         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3738   "TARGET_64BIT"
3739   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3740    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3741   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3743 (define_expand "extendsfdf2"
3744   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3745         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3746   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3748   /* ??? Needed for compress_float_constant since all fp constants
3749      are LEGITIMATE_CONSTANT_P.  */
3750   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3751     {
3752       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3753           && standard_80387_constant_p (operands[1]) > 0)
3754         {
3755           operands[1] = simplify_const_unary_operation
3756             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3757           emit_move_insn_1 (operands[0], operands[1]);
3758           DONE;
3759         }
3760       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3761     }
3764 (define_insn "*extendsfdf2_mixed"
3765   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3766         (float_extend:DF
3767           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3768   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3770   switch (which_alternative)
3771     {
3772     case 0:
3773     case 1:
3774       return output_387_reg_move (insn, operands);
3776     case 2:
3777       return "cvtss2sd\t{%1, %0|%0, %1}";
3779     default:
3780       gcc_unreachable ();
3781     }
3783   [(set_attr "type" "fmov,fmov,ssecvt")
3784    (set_attr "mode" "SF,XF,DF")])
3786 (define_insn "*extendsfdf2_sse"
3787   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3788         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3789   "TARGET_SSE2 && TARGET_SSE_MATH"
3790   "cvtss2sd\t{%1, %0|%0, %1}"
3791   [(set_attr "type" "ssecvt")
3792    (set_attr "mode" "DF")])
3794 (define_insn "*extendsfdf2_i387"
3795   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3796         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3797   "TARGET_80387"
3798   "* return output_387_reg_move (insn, operands);"
3799   [(set_attr "type" "fmov")
3800    (set_attr "mode" "SF,XF")])
3802 (define_expand "extend<mode>xf2"
3803   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3804         (float_extend:XF (match_operand:X87MODEF12 1 "general_operand" "")))]
3805   "TARGET_80387"
3807   /* ??? Needed for compress_float_constant since all fp constants
3808      are LEGITIMATE_CONSTANT_P.  */
3809   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3810     {
3811       if (standard_80387_constant_p (operands[1]) > 0)
3812         {
3813           operands[1] = simplify_const_unary_operation
3814             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3815           emit_move_insn_1 (operands[0], operands[1]);
3816           DONE;
3817         }
3818       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3819     }
3822 (define_insn "*extend<mode>xf2_i387"
3823   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3824         (float_extend:XF
3825           (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,f")))]
3826   "TARGET_80387"
3827   "* return output_387_reg_move (insn, operands);"
3828   [(set_attr "type" "fmov")
3829    (set_attr "mode" "<MODE>,XF")])
3831 ;; %%% This seems bad bad news.
3832 ;; This cannot output into an f-reg because there is no way to be sure
3833 ;; of truncating in that case.  Otherwise this is just like a simple move
3834 ;; insn.  So we pretend we can output to a reg in order to get better
3835 ;; register preferencing, but we really use a stack slot.
3837 ;; Conversion from DFmode to SFmode.
3839 (define_expand "truncdfsf2"
3840   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3841         (float_truncate:SF
3842           (match_operand:DF 1 "nonimmediate_operand" "")))]
3843   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3845   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3846     ;
3847   else if (flag_unsafe_math_optimizations)
3848     ;
3849   else
3850     {
3851       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3852       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3853       DONE;
3854     }
3857 (define_expand "truncdfsf2_with_temp"
3858   [(parallel [(set (match_operand:SF 0 "" "")
3859                    (float_truncate:SF (match_operand:DF 1 "" "")))
3860               (clobber (match_operand:SF 2 "" ""))])]
3861   "")
3863 (define_insn "*truncdfsf_fast_mixed"
3864   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
3865         (float_truncate:SF
3866           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3867   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3869   switch (which_alternative)
3870     {
3871     case 0:
3872     case 1:
3873       return output_387_reg_move (insn, operands);
3874     case 2:
3875       return "cvtsd2ss\t{%1, %0|%0, %1}";
3876     default:
3877       gcc_unreachable ();
3878     }
3880   [(set_attr "type" "fmov,fmov,ssecvt")
3881    (set_attr "mode" "SF")])
3883 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3884 ;; because nothing we do here is unsafe.
3885 (define_insn "*truncdfsf_fast_sse"
3886   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3887         (float_truncate:SF
3888           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3889   "TARGET_SSE2 && TARGET_SSE_MATH"
3890   "cvtsd2ss\t{%1, %0|%0, %1}"
3891   [(set_attr "type" "ssecvt")
3892    (set_attr "mode" "SF")])
3894 (define_insn "*truncdfsf_fast_i387"
3895   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3896         (float_truncate:SF
3897           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3898   "TARGET_80387 && flag_unsafe_math_optimizations"
3899   "* return output_387_reg_move (insn, operands);"
3900   [(set_attr "type" "fmov")
3901    (set_attr "mode" "SF")])
3903 (define_insn "*truncdfsf_mixed"
3904   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
3905         (float_truncate:SF
3906           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
3907    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3908   "TARGET_MIX_SSE_I387"
3910   switch (which_alternative)
3911     {
3912     case 0:
3913       return output_387_reg_move (insn, operands);
3915     case 1:
3916       return "#";
3917     case 2:
3918       return "cvtsd2ss\t{%1, %0|%0, %1}";
3919     default:
3920       gcc_unreachable ();
3921     }
3923   [(set_attr "type" "fmov,multi,ssecvt")
3924    (set_attr "unit" "*,i387,*")
3925    (set_attr "mode" "SF")])
3927 (define_insn "*truncdfsf_i387"
3928   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3929         (float_truncate:SF
3930           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3931    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3932   "TARGET_80387"
3934   switch (which_alternative)
3935     {
3936     case 0:
3937       return output_387_reg_move (insn, operands);
3939     case 1:
3940       return "#";
3941     default:
3942       gcc_unreachable ();
3943     }
3945   [(set_attr "type" "fmov,multi")
3946    (set_attr "unit" "*,i387")
3947    (set_attr "mode" "SF")])
3949 (define_insn "*truncdfsf2_i387_1"
3950   [(set (match_operand:SF 0 "memory_operand" "=m")
3951         (float_truncate:SF
3952           (match_operand:DF 1 "register_operand" "f")))]
3953   "TARGET_80387
3954    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3955    && !TARGET_MIX_SSE_I387"
3956   "* return output_387_reg_move (insn, operands);"
3957   [(set_attr "type" "fmov")
3958    (set_attr "mode" "SF")])
3960 (define_split
3961   [(set (match_operand:SF 0 "register_operand" "")
3962         (float_truncate:SF
3963          (match_operand:DF 1 "fp_register_operand" "")))
3964    (clobber (match_operand 2 "" ""))]
3965   "reload_completed"
3966   [(set (match_dup 2) (match_dup 1))
3967    (set (match_dup 0) (match_dup 2))]
3969   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3972 ;; Conversion from XFmode to {SF,DF}mode
3974 (define_expand "truncxf<mode>2"
3975   [(parallel [(set (match_operand:X87MODEF12 0 "nonimmediate_operand" "")
3976                    (float_truncate:X87MODEF12
3977                      (match_operand:XF 1 "register_operand" "")))
3978               (clobber (match_dup 2))])]
3979   "TARGET_80387"
3981   if (flag_unsafe_math_optimizations)
3982     {
3983       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3984       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3985       if (reg != operands[0])
3986         emit_move_insn (operands[0], reg);
3987       DONE;
3988     }
3989   else
3990     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3993 (define_insn "*truncxfsf2_mixed"
3994   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3995         (float_truncate:SF
3996           (match_operand:XF 1 "register_operand" "f,f")))
3997    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3998   "TARGET_80387"
4000   gcc_assert (!which_alternative);
4001   return output_387_reg_move (insn, operands);
4003   [(set_attr "type" "fmov,multi")
4004    (set_attr "unit" "*,i387")
4005    (set_attr "mode" "SF")])
4007 (define_insn "*truncxfdf2_mixed"
4008   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4009         (float_truncate:DF
4010           (match_operand:XF 1 "register_operand" "f,f")))
4011    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4012   "TARGET_80387"
4014   gcc_assert (!which_alternative);
4015   return output_387_reg_move (insn, operands);
4017   [(set_attr "type" "fmov,multi")
4018    (set_attr "unit" "*,i387")
4019    (set_attr "mode" "DF")])
4021 (define_insn "truncxf<mode>2_i387_noop"
4022   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
4023         (float_truncate:X87MODEF12
4024           (match_operand:XF 1 "register_operand" "f")))]
4025   "TARGET_80387 && flag_unsafe_math_optimizations"
4026   "* return output_387_reg_move (insn, operands);"
4027   [(set_attr "type" "fmov")
4028    (set_attr "mode" "<MODE>")])
4030 (define_insn "*truncxf<mode>2_i387"
4031   [(set (match_operand:X87MODEF12 0 "memory_operand" "=m")
4032         (float_truncate:X87MODEF12
4033           (match_operand:XF 1 "register_operand" "f")))]
4034   "TARGET_80387"
4035   "* return output_387_reg_move (insn, operands);"
4036   [(set_attr "type" "fmov")
4037    (set_attr "mode" "<MODE>")])
4039 (define_split
4040   [(set (match_operand:X87MODEF12 0 "register_operand" "")
4041         (float_truncate:X87MODEF12
4042           (match_operand:XF 1 "register_operand" "")))
4043    (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4044   "TARGET_80387 && reload_completed"
4045   [(set (match_dup 2) (float_truncate:X87MODEF12 (match_dup 1)))
4046    (set (match_dup 0) (match_dup 2))]
4047   "")
4049 (define_split
4050   [(set (match_operand:X87MODEF12 0 "memory_operand" "")
4051         (float_truncate:X87MODEF12
4052           (match_operand:XF 1 "register_operand" "")))
4053    (clobber (match_operand:X87MODEF12 2 "memory_operand" ""))]
4054   "TARGET_80387"
4055   [(set (match_dup 0) (float_truncate:X87MODEF12 (match_dup 1)))]
4056   "")
4058 ;; Signed conversion to DImode.
4060 (define_expand "fix_truncxfdi2"
4061   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4062                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4063               (clobber (reg:CC FLAGS_REG))])]
4064   "TARGET_80387"
4066   if (TARGET_FISTTP)
4067    {
4068      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4069      DONE;
4070    }
4073 (define_expand "fix_trunc<mode>di2"
4074   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4075                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4076               (clobber (reg:CC FLAGS_REG))])]
4077   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4079   if (TARGET_FISTTP
4080       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4081    {
4082      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4083      DONE;
4084    }
4085   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4086    {
4087      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4088      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4089      if (out != operands[0])
4090         emit_move_insn (operands[0], out);
4091      DONE;
4092    }
4095 ;; Signed conversion to SImode.
4097 (define_expand "fix_truncxfsi2"
4098   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4099                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4100               (clobber (reg:CC FLAGS_REG))])]
4101   "TARGET_80387"
4103   if (TARGET_FISTTP)
4104    {
4105      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4106      DONE;
4107    }
4110 (define_expand "fix_trunc<mode>si2"
4111   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4112                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4113               (clobber (reg:CC FLAGS_REG))])]
4114   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4116   if (TARGET_FISTTP
4117       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4118    {
4119      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4120      DONE;
4121    }
4122   if (SSE_FLOAT_MODE_P (<MODE>mode))
4123    {
4124      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4125      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4126      if (out != operands[0])
4127         emit_move_insn (operands[0], out);
4128      DONE;
4129    }
4132 ;; Signed conversion to HImode.
4134 (define_expand "fix_trunc<mode>hi2"
4135   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4136                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4137               (clobber (reg:CC FLAGS_REG))])]
4138   "TARGET_80387
4139    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4141   if (TARGET_FISTTP)
4142    {
4143      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4144      DONE;
4145    }
4148 ;; Unsigned conversion to SImode.
4150 (define_expand "fixuns_trunc<mode>si2"
4151   [(parallel
4152     [(set (match_operand:SI 0 "register_operand" "")
4153           (unsigned_fix:SI
4154             (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4155      (use (match_dup 2))
4156      (clobber (match_scratch:<ssevecmode> 3 ""))
4157      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4158   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4160   enum machine_mode mode = <MODE>mode;
4161   enum machine_mode vecmode = <ssevecmode>mode;
4162   REAL_VALUE_TYPE TWO31r;
4163   rtx two31;
4165   real_ldexp (&TWO31r, &dconst1, 31);
4166   two31 = const_double_from_real_value (TWO31r, mode);
4167   two31 = ix86_build_const_vector (mode, true, two31);
4168   operands[2] = force_reg (vecmode, two31);
4171 (define_insn_and_split "*fixuns_trunc<mode>_1"
4172   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4173         (unsigned_fix:SI
4174           (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4175    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4176    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4177    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4178   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4179   "#"
4180   "&& reload_completed"
4181   [(const_int 0)]
4183   ix86_split_convert_uns_si_sse (operands);
4184   DONE;
4187 ;; Unsigned conversion to HImode.
4188 ;; Without these patterns, we'll try the unsigned SI conversion which
4189 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4191 (define_expand "fixuns_trunc<mode>hi2"
4192   [(set (match_dup 2)
4193         (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4194    (set (match_operand:HI 0 "nonimmediate_operand" "")
4195         (subreg:HI (match_dup 2) 0))]
4196   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4197   "operands[2] = gen_reg_rtx (SImode);")
4199 ;; When SSE is available, it is always faster to use it!
4200 (define_insn "fix_trunc<mode>di_sse"
4201   [(set (match_operand:DI 0 "register_operand" "=r,r")
4202         (fix:DI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4203   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4204    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4205   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4206   [(set_attr "type" "sseicvt")
4207    (set_attr "mode" "<MODE>")
4208    (set_attr "athlon_decode" "double,vector")
4209    (set_attr "amdfam10_decode" "double,double")])
4211 (define_insn "fix_trunc<mode>si_sse"
4212   [(set (match_operand:SI 0 "register_operand" "=r,r")
4213         (fix:SI (match_operand:SSEMODEF 1 "nonimmediate_operand" "x,m")))]
4214   "SSE_FLOAT_MODE_P (<MODE>mode)
4215    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4216   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4217   [(set_attr "type" "sseicvt")
4218    (set_attr "mode" "<MODE>")
4219    (set_attr "athlon_decode" "double,vector")
4220    (set_attr "amdfam10_decode" "double,double")])
4222 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4223 (define_peephole2
4224   [(set (match_operand:SSEMODEF 0 "register_operand" "")
4225         (match_operand:SSEMODEF 1 "memory_operand" ""))
4226    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4227         (fix:SSEMODEI24 (match_dup 0)))]
4228   "TARGET_SHORTEN_X87_SSE
4229    && peep2_reg_dead_p (2, operands[0])"
4230   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4231   "")
4233 ;; Avoid vector decoded forms of the instruction.
4234 (define_peephole2
4235   [(match_scratch:DF 2 "Y2")
4236    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4237         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4238   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4239   [(set (match_dup 2) (match_dup 1))
4240    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4241   "")
4243 (define_peephole2
4244   [(match_scratch:SF 2 "x")
4245    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4246         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4247   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4248   [(set (match_dup 2) (match_dup 1))
4249    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4250   "")
4252 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4253   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4254         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4255   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4256    && TARGET_FISTTP
4257    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4258          && (TARGET_64BIT || <MODE>mode != DImode))
4259         && TARGET_SSE_MATH)
4260    && !(reload_completed || reload_in_progress)"
4261   "#"
4262   "&& 1"
4263   [(const_int 0)]
4265   if (memory_operand (operands[0], VOIDmode))
4266     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4267   else
4268     {
4269       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4270       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4271                                                             operands[1],
4272                                                             operands[2]));
4273     }
4274   DONE;
4276   [(set_attr "type" "fisttp")
4277    (set_attr "mode" "<MODE>")])
4279 (define_insn "fix_trunc<mode>_i387_fisttp"
4280   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4281         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4282    (clobber (match_scratch:XF 2 "=&1f"))]
4283   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4284    && TARGET_FISTTP
4285    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4286          && (TARGET_64BIT || <MODE>mode != DImode))
4287         && TARGET_SSE_MATH)"
4288   "* return output_fix_trunc (insn, operands, 1);"
4289   [(set_attr "type" "fisttp")
4290    (set_attr "mode" "<MODE>")])
4292 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4293   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4294         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4295    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4296    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4297   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4298    && TARGET_FISTTP
4299    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4300         && (TARGET_64BIT || <MODE>mode != DImode))
4301         && TARGET_SSE_MATH)"
4302   "#"
4303   [(set_attr "type" "fisttp")
4304    (set_attr "mode" "<MODE>")])
4306 (define_split
4307   [(set (match_operand:X87MODEI 0 "register_operand" "")
4308         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4309    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4310    (clobber (match_scratch 3 ""))]
4311   "reload_completed"
4312   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4313               (clobber (match_dup 3))])
4314    (set (match_dup 0) (match_dup 2))]
4315   "")
4317 (define_split
4318   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4319         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4320    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4321    (clobber (match_scratch 3 ""))]
4322   "reload_completed"
4323   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4324               (clobber (match_dup 3))])]
4325   "")
4327 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4328 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4329 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4330 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4331 ;; function in i386.c.
4332 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4333   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4334         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4335    (clobber (reg:CC FLAGS_REG))]
4336   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4337    && !TARGET_FISTTP
4338    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4339          && (TARGET_64BIT || <MODE>mode != DImode))
4340    && !(reload_completed || reload_in_progress)"
4341   "#"
4342   "&& 1"
4343   [(const_int 0)]
4345   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4347   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4348   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4349   if (memory_operand (operands[0], VOIDmode))
4350     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4351                                          operands[2], operands[3]));
4352   else
4353     {
4354       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4355       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4356                                                      operands[2], operands[3],
4357                                                      operands[4]));
4358     }
4359   DONE;
4361   [(set_attr "type" "fistp")
4362    (set_attr "i387_cw" "trunc")
4363    (set_attr "mode" "<MODE>")])
4365 (define_insn "fix_truncdi_i387"
4366   [(set (match_operand:DI 0 "memory_operand" "=m")
4367         (fix:DI (match_operand 1 "register_operand" "f")))
4368    (use (match_operand:HI 2 "memory_operand" "m"))
4369    (use (match_operand:HI 3 "memory_operand" "m"))
4370    (clobber (match_scratch:XF 4 "=&1f"))]
4371   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4372    && !TARGET_FISTTP
4373    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4374   "* return output_fix_trunc (insn, operands, 0);"
4375   [(set_attr "type" "fistp")
4376    (set_attr "i387_cw" "trunc")
4377    (set_attr "mode" "DI")])
4379 (define_insn "fix_truncdi_i387_with_temp"
4380   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4381         (fix:DI (match_operand 1 "register_operand" "f,f")))
4382    (use (match_operand:HI 2 "memory_operand" "m,m"))
4383    (use (match_operand:HI 3 "memory_operand" "m,m"))
4384    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4385    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4386   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4387    && !TARGET_FISTTP
4388    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4389   "#"
4390   [(set_attr "type" "fistp")
4391    (set_attr "i387_cw" "trunc")
4392    (set_attr "mode" "DI")])
4394 (define_split
4395   [(set (match_operand:DI 0 "register_operand" "")
4396         (fix:DI (match_operand 1 "register_operand" "")))
4397    (use (match_operand:HI 2 "memory_operand" ""))
4398    (use (match_operand:HI 3 "memory_operand" ""))
4399    (clobber (match_operand:DI 4 "memory_operand" ""))
4400    (clobber (match_scratch 5 ""))]
4401   "reload_completed"
4402   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4403               (use (match_dup 2))
4404               (use (match_dup 3))
4405               (clobber (match_dup 5))])
4406    (set (match_dup 0) (match_dup 4))]
4407   "")
4409 (define_split
4410   [(set (match_operand:DI 0 "memory_operand" "")
4411         (fix:DI (match_operand 1 "register_operand" "")))
4412    (use (match_operand:HI 2 "memory_operand" ""))
4413    (use (match_operand:HI 3 "memory_operand" ""))
4414    (clobber (match_operand:DI 4 "memory_operand" ""))
4415    (clobber (match_scratch 5 ""))]
4416   "reload_completed"
4417   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4418               (use (match_dup 2))
4419               (use (match_dup 3))
4420               (clobber (match_dup 5))])]
4421   "")
4423 (define_insn "fix_trunc<mode>_i387"
4424   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4425         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4426    (use (match_operand:HI 2 "memory_operand" "m"))
4427    (use (match_operand:HI 3 "memory_operand" "m"))]
4428   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4429    && !TARGET_FISTTP
4430    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4431   "* return output_fix_trunc (insn, operands, 0);"
4432   [(set_attr "type" "fistp")
4433    (set_attr "i387_cw" "trunc")
4434    (set_attr "mode" "<MODE>")])
4436 (define_insn "fix_trunc<mode>_i387_with_temp"
4437   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4438         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4439    (use (match_operand:HI 2 "memory_operand" "m,m"))
4440    (use (match_operand:HI 3 "memory_operand" "m,m"))
4441    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4442   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4443    && !TARGET_FISTTP
4444    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4445   "#"
4446   [(set_attr "type" "fistp")
4447    (set_attr "i387_cw" "trunc")
4448    (set_attr "mode" "<MODE>")])
4450 (define_split
4451   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4452         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4453    (use (match_operand:HI 2 "memory_operand" ""))
4454    (use (match_operand:HI 3 "memory_operand" ""))
4455    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4456   "reload_completed"
4457   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4458               (use (match_dup 2))
4459               (use (match_dup 3))])
4460    (set (match_dup 0) (match_dup 4))]
4461   "")
4463 (define_split
4464   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4465         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4466    (use (match_operand:HI 2 "memory_operand" ""))
4467    (use (match_operand:HI 3 "memory_operand" ""))
4468    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4469   "reload_completed"
4470   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4471               (use (match_dup 2))
4472               (use (match_dup 3))])]
4473   "")
4475 (define_insn "x86_fnstcw_1"
4476   [(set (match_operand:HI 0 "memory_operand" "=m")
4477         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4478   "TARGET_80387"
4479   "fnstcw\t%0"
4480   [(set_attr "length" "2")
4481    (set_attr "mode" "HI")
4482    (set_attr "unit" "i387")])
4484 (define_insn "x86_fldcw_1"
4485   [(set (reg:HI FPCR_REG)
4486         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4487   "TARGET_80387"
4488   "fldcw\t%0"
4489   [(set_attr "length" "2")
4490    (set_attr "mode" "HI")
4491    (set_attr "unit" "i387")
4492    (set_attr "athlon_decode" "vector")
4493    (set_attr "amdfam10_decode" "vector")])   
4495 ;; Conversion between fixed point and floating point.
4497 ;; Even though we only accept memory inputs, the backend _really_
4498 ;; wants to be able to do this between registers.
4500 (define_expand "floathi<mode>2"
4501   [(set (match_operand:SSEMODEF 0 "register_operand" "")
4502         (float:SSEMODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4503   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4505   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4506     {
4507       emit_insn
4508         (gen_floatsi<mode>2 (operands[0],
4509                              convert_to_mode (SImode, operands[1], 0)));
4510       DONE;
4511     }
4514 (define_insn "*floathi<mode>2_i387"
4515   [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4516         (float:X87MODEF12
4517           (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4518   "TARGET_80387
4519    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4520        || TARGET_MIX_SSE_I387)"
4521   "@
4522    fild%z1\t%1
4523    #"
4524   [(set_attr "type" "fmov,multi")
4525    (set_attr "mode" "<MODE>")
4526    (set_attr "unit" "*,i387")
4527    (set_attr "fp_int_src" "true")])
4529 (define_expand "floatsi<mode>2"
4530   [(set (match_operand:SSEMODEF 0 "register_operand" "")
4531         (float:SSEMODEF (match_operand:SI 1 "nonimmediate_operand" "")))]
4532   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
4533   "")
4535 (define_insn "*floatsisf2_mixed"
4536   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4537         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4538   "TARGET_MIX_SSE_I387"
4539   "@
4540    fild%z1\t%1
4541    #
4542    cvtsi2ss\t{%1, %0|%0, %1}
4543    cvtsi2ss\t{%1, %0|%0, %1}"
4544   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4545    (set_attr "mode" "SF")
4546    (set_attr "unit" "*,i387,*,*")
4547    (set_attr "athlon_decode" "*,*,vector,double")
4548    (set_attr "amdfam10_decode" "*,*,vector,double")
4549    (set_attr "fp_int_src" "true")])
4551 (define_insn "*floatsisf2_sse"
4552   [(set (match_operand:SF 0 "register_operand" "=x,x")
4553         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4554   "TARGET_SSE_MATH"
4555   "cvtsi2ss\t{%1, %0|%0, %1}"
4556   [(set_attr "type" "sseicvt")
4557    (set_attr "mode" "SF")
4558    (set_attr "athlon_decode" "vector,double")
4559    (set_attr "amdfam10_decode" "vector,double")
4560    (set_attr "fp_int_src" "true")])
4562 (define_insn "*floatsidf2_mixed"
4563   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4564         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,m")))]
4565   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4566   "@
4567    fild%z1\t%1
4568    #
4569    cvtsi2sd\t{%1, %0|%0, %1}
4570    cvtsi2sd\t{%1, %0|%0, %1}"
4571   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4572    (set_attr "mode" "DF")
4573    (set_attr "unit" "*,i387,*,*")
4574    (set_attr "athlon_decode" "*,*,double,direct")
4575    (set_attr "amdfam10_decode" "*,*,vector,double")
4576    (set_attr "fp_int_src" "true")])
4578 (define_insn "*floatsidf2_sse"
4579   [(set (match_operand:DF 0 "register_operand" "=x,x")
4580         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
4581   "TARGET_SSE2 && TARGET_SSE_MATH"
4582   "cvtsi2sd\t{%1, %0|%0, %1}"
4583   [(set_attr "type" "sseicvt")
4584    (set_attr "mode" "DF")
4585    (set_attr "athlon_decode" "double,direct")
4586    (set_attr "amdfam10_decode" "vector,double")
4587    (set_attr "fp_int_src" "true")])
4589 (define_insn "*floatsi<mode>2_i387"
4590   [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4591         (float:X87MODEF12
4592           (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4593   "TARGET_80387"
4594   "@
4595    fild%z1\t%1
4596    #"
4597   [(set_attr "type" "fmov,multi")
4598    (set_attr "mode" "<MODE>")
4599    (set_attr "unit" "*,i387")
4600    (set_attr "fp_int_src" "true")])
4602 (define_expand "floatdisf2"
4603   [(set (match_operand:SF 0 "register_operand" "")
4604         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4605   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4606   "")
4608 (define_insn "*floatdisf2_mixed"
4609   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4610         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4611   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4612   "@
4613    fild%z1\t%1
4614    #
4615    cvtsi2ss{q}\t{%1, %0|%0, %1}
4616    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4617   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4618    (set_attr "mode" "SF")
4619    (set_attr "unit" "*,i387,*,*")
4620    (set_attr "athlon_decode" "*,*,vector,double")
4621    (set_attr "amdfam10_decode" "*,*,vector,double")
4622    (set_attr "fp_int_src" "true")])
4624 (define_insn "*floatdisf2_sse"
4625   [(set (match_operand:SF 0 "register_operand" "=x,x")
4626         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4627   "TARGET_64BIT && TARGET_SSE_MATH"
4628   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4629   [(set_attr "type" "sseicvt")
4630    (set_attr "mode" "SF")
4631    (set_attr "athlon_decode" "vector,double")
4632    (set_attr "amdfam10_decode" "vector,double")
4633    (set_attr "fp_int_src" "true")])
4635 (define_expand "floatdidf2"
4636   [(set (match_operand:DF 0 "register_operand" "")
4637         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4638   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4640   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4641     {
4642       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4643       DONE;
4644     }
4647 (define_insn "*floatdidf2_mixed"
4648   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4649         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,m")))]
4650   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4651   "@
4652    fild%z1\t%1
4653    #
4654    cvtsi2sd{q}\t{%1, %0|%0, %1}
4655    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4656   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4657    (set_attr "mode" "DF")
4658    (set_attr "unit" "*,i387,*,*")
4659    (set_attr "athlon_decode" "*,*,double,direct")
4660    (set_attr "amdfam10_decode" "*,*,vector,double")
4661    (set_attr "fp_int_src" "true")])
4663 (define_insn "*floatdidf2_sse"
4664   [(set (match_operand:DF 0 "register_operand" "=x,x")
4665         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,m")))]
4666   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4667   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4668   [(set_attr "type" "sseicvt")
4669    (set_attr "mode" "DF")
4670    (set_attr "athlon_decode" "double,direct")
4671    (set_attr "amdfam10_decode" "vector,double")
4672    (set_attr "fp_int_src" "true")])
4674 (define_insn "*floatdi<mode>2_i387"
4675   [(set (match_operand:X87MODEF12 0 "register_operand" "=f,f")
4676         (float:X87MODEF12
4677           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4678   "TARGET_80387"
4679   "@
4680    fild%z1\t%1
4681    #"
4682   [(set_attr "type" "fmov,multi")
4683    (set_attr "mode" "<MODE>")
4684    (set_attr "unit" "*,i387")
4685    (set_attr "fp_int_src" "true")])
4687 (define_insn "float<mode>xf2"
4688   [(set (match_operand:XF 0 "register_operand" "=f,f")
4689         (float:XF (match_operand:X87MODEI 1 "nonimmediate_operand" "m,?r")))]
4690   "TARGET_80387"
4691   "@
4692    fild%z1\t%1
4693    #"
4694   [(set_attr "type" "fmov,multi")
4695    (set_attr "mode" "XF")
4696    (set_attr "unit" "*,i387")
4697    (set_attr "fp_int_src" "true")])
4699 ;; %%% Kill these when reload knows how to do it.
4700 (define_split
4701   [(set (match_operand 0 "fp_register_operand" "")
4702         (float (match_operand 1 "register_operand" "")))]
4703   "reload_completed
4704    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
4705   [(const_int 0)]
4707   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4708   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4709   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4710   ix86_free_from_memory (GET_MODE (operands[1]));
4711   DONE;
4714 (define_expand "floatunssisf2"
4715   [(use (match_operand:SF 0 "register_operand" ""))
4716    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4717   "!TARGET_64BIT"
4719   if (TARGET_SSE_MATH && TARGET_SSE2)
4720     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4721   else
4722     x86_emit_floatuns (operands);
4723   DONE;
4726 (define_expand "floatunssidf2"
4727   [(use (match_operand:DF 0 "register_operand" ""))
4728    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4729   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4730   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
4732 (define_expand "floatunsdisf2"
4733   [(use (match_operand:SF 0 "register_operand" ""))
4734    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4735   "TARGET_64BIT && TARGET_SSE_MATH"
4736   "x86_emit_floatuns (operands); DONE;")
4738 (define_expand "floatunsdidf2"
4739   [(use (match_operand:DF 0 "register_operand" ""))
4740    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
4741   "TARGET_SSE_MATH && TARGET_SSE2
4742    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
4744   if (TARGET_64BIT)
4745     x86_emit_floatuns (operands);
4746   else
4747     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
4748   DONE;
4751 ;; Add instructions
4753 ;; %%% splits for addditi3
4755 (define_expand "addti3"
4756   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4757         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4758                  (match_operand:TI 2 "x86_64_general_operand" "")))
4759    (clobber (reg:CC FLAGS_REG))]
4760   "TARGET_64BIT"
4761   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4763 (define_insn "*addti3_1"
4764   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4765         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4766                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4767    (clobber (reg:CC FLAGS_REG))]
4768   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4769   "#")
4771 (define_split
4772   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4773         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4774                  (match_operand:TI 2 "x86_64_general_operand" "")))
4775    (clobber (reg:CC FLAGS_REG))]
4776   "TARGET_64BIT && reload_completed"
4777   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4778                                           UNSPEC_ADD_CARRY))
4779               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4780    (parallel [(set (match_dup 3)
4781                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4782                                      (match_dup 4))
4783                             (match_dup 5)))
4784               (clobber (reg:CC FLAGS_REG))])]
4785   "split_ti (operands+0, 1, operands+0, operands+3);
4786    split_ti (operands+1, 1, operands+1, operands+4);
4787    split_ti (operands+2, 1, operands+2, operands+5);")
4789 ;; %%% splits for addsidi3
4790 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4791 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4792 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4794 (define_expand "adddi3"
4795   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4796         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4797                  (match_operand:DI 2 "x86_64_general_operand" "")))
4798    (clobber (reg:CC FLAGS_REG))]
4799   ""
4800   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4802 (define_insn "*adddi3_1"
4803   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4804         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4805                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4806    (clobber (reg:CC FLAGS_REG))]
4807   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4808   "#")
4810 (define_split
4811   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4812         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4813                  (match_operand:DI 2 "general_operand" "")))
4814    (clobber (reg:CC FLAGS_REG))]
4815   "!TARGET_64BIT && reload_completed"
4816   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4817                                           UNSPEC_ADD_CARRY))
4818               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4819    (parallel [(set (match_dup 3)
4820                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4821                                      (match_dup 4))
4822                             (match_dup 5)))
4823               (clobber (reg:CC FLAGS_REG))])]
4824   "split_di (operands+0, 1, operands+0, operands+3);
4825    split_di (operands+1, 1, operands+1, operands+4);
4826    split_di (operands+2, 1, operands+2, operands+5);")
4828 (define_insn "adddi3_carry_rex64"
4829   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4830           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4831                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4832                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4833    (clobber (reg:CC FLAGS_REG))]
4834   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4835   "adc{q}\t{%2, %0|%0, %2}"
4836   [(set_attr "type" "alu")
4837    (set_attr "pent_pair" "pu")
4838    (set_attr "mode" "DI")])
4840 (define_insn "*adddi3_cc_rex64"
4841   [(set (reg:CC FLAGS_REG)
4842         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4843                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4844                    UNSPEC_ADD_CARRY))
4845    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4846         (plus:DI (match_dup 1) (match_dup 2)))]
4847   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4848   "add{q}\t{%2, %0|%0, %2}"
4849   [(set_attr "type" "alu")
4850    (set_attr "mode" "DI")])
4852 (define_insn "addqi3_carry"
4853   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4854           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4855                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4856                    (match_operand:QI 2 "general_operand" "qi,qm")))
4857    (clobber (reg:CC FLAGS_REG))]
4858   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4859   "adc{b}\t{%2, %0|%0, %2}"
4860   [(set_attr "type" "alu")
4861    (set_attr "pent_pair" "pu")
4862    (set_attr "mode" "QI")])
4864 (define_insn "addhi3_carry"
4865   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4866           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4867                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4868                    (match_operand:HI 2 "general_operand" "ri,rm")))
4869    (clobber (reg:CC FLAGS_REG))]
4870   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4871   "adc{w}\t{%2, %0|%0, %2}"
4872   [(set_attr "type" "alu")
4873    (set_attr "pent_pair" "pu")
4874    (set_attr "mode" "HI")])
4876 (define_insn "addsi3_carry"
4877   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4878           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4879                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4880                    (match_operand:SI 2 "general_operand" "ri,rm")))
4881    (clobber (reg:CC FLAGS_REG))]
4882   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4883   "adc{l}\t{%2, %0|%0, %2}"
4884   [(set_attr "type" "alu")
4885    (set_attr "pent_pair" "pu")
4886    (set_attr "mode" "SI")])
4888 (define_insn "*addsi3_carry_zext"
4889   [(set (match_operand:DI 0 "register_operand" "=r")
4890           (zero_extend:DI
4891             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4892                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4893                      (match_operand:SI 2 "general_operand" "rim"))))
4894    (clobber (reg:CC FLAGS_REG))]
4895   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4896   "adc{l}\t{%2, %k0|%k0, %2}"
4897   [(set_attr "type" "alu")
4898    (set_attr "pent_pair" "pu")
4899    (set_attr "mode" "SI")])
4901 (define_insn "*addsi3_cc"
4902   [(set (reg:CC FLAGS_REG)
4903         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4904                     (match_operand:SI 2 "general_operand" "ri,rm")]
4905                    UNSPEC_ADD_CARRY))
4906    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4907         (plus:SI (match_dup 1) (match_dup 2)))]
4908   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4909   "add{l}\t{%2, %0|%0, %2}"
4910   [(set_attr "type" "alu")
4911    (set_attr "mode" "SI")])
4913 (define_insn "addqi3_cc"
4914   [(set (reg:CC FLAGS_REG)
4915         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4916                     (match_operand:QI 2 "general_operand" "qi,qm")]
4917                    UNSPEC_ADD_CARRY))
4918    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4919         (plus:QI (match_dup 1) (match_dup 2)))]
4920   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4921   "add{b}\t{%2, %0|%0, %2}"
4922   [(set_attr "type" "alu")
4923    (set_attr "mode" "QI")])
4925 (define_expand "addsi3"
4926   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4927                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4928                             (match_operand:SI 2 "general_operand" "")))
4929               (clobber (reg:CC FLAGS_REG))])]
4930   ""
4931   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4933 (define_insn "*lea_1"
4934   [(set (match_operand:SI 0 "register_operand" "=r")
4935         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4936   "!TARGET_64BIT"
4937   "lea{l}\t{%a1, %0|%0, %a1}"
4938   [(set_attr "type" "lea")
4939    (set_attr "mode" "SI")])
4941 (define_insn "*lea_1_rex64"
4942   [(set (match_operand:SI 0 "register_operand" "=r")
4943         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4944   "TARGET_64BIT"
4945   "lea{l}\t{%a1, %0|%0, %a1}"
4946   [(set_attr "type" "lea")
4947    (set_attr "mode" "SI")])
4949 (define_insn "*lea_1_zext"
4950   [(set (match_operand:DI 0 "register_operand" "=r")
4951         (zero_extend:DI
4952          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4953   "TARGET_64BIT"
4954   "lea{l}\t{%a1, %k0|%k0, %a1}"
4955   [(set_attr "type" "lea")
4956    (set_attr "mode" "SI")])
4958 (define_insn "*lea_2_rex64"
4959   [(set (match_operand:DI 0 "register_operand" "=r")
4960         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4961   "TARGET_64BIT"
4962   "lea{q}\t{%a1, %0|%0, %a1}"
4963   [(set_attr "type" "lea")
4964    (set_attr "mode" "DI")])
4966 ;; The lea patterns for non-Pmodes needs to be matched by several
4967 ;; insns converted to real lea by splitters.
4969 (define_insn_and_split "*lea_general_1"
4970   [(set (match_operand 0 "register_operand" "=r")
4971         (plus (plus (match_operand 1 "index_register_operand" "l")
4972                     (match_operand 2 "register_operand" "r"))
4973               (match_operand 3 "immediate_operand" "i")))]
4974   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4975     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4976    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4977    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4978    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4979    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4980        || GET_MODE (operands[3]) == VOIDmode)"
4981   "#"
4982   "&& reload_completed"
4983   [(const_int 0)]
4985   rtx pat;
4986   operands[0] = gen_lowpart (SImode, operands[0]);
4987   operands[1] = gen_lowpart (Pmode, operands[1]);
4988   operands[2] = gen_lowpart (Pmode, operands[2]);
4989   operands[3] = gen_lowpart (Pmode, operands[3]);
4990   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4991                       operands[3]);
4992   if (Pmode != SImode)
4993     pat = gen_rtx_SUBREG (SImode, pat, 0);
4994   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4995   DONE;
4997   [(set_attr "type" "lea")
4998    (set_attr "mode" "SI")])
5000 (define_insn_and_split "*lea_general_1_zext"
5001   [(set (match_operand:DI 0 "register_operand" "=r")
5002         (zero_extend:DI
5003           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5004                             (match_operand:SI 2 "register_operand" "r"))
5005                    (match_operand:SI 3 "immediate_operand" "i"))))]
5006   "TARGET_64BIT"
5007   "#"
5008   "&& reload_completed"
5009   [(set (match_dup 0)
5010         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5011                                                      (match_dup 2))
5012                                             (match_dup 3)) 0)))]
5014   operands[1] = gen_lowpart (Pmode, operands[1]);
5015   operands[2] = gen_lowpart (Pmode, operands[2]);
5016   operands[3] = gen_lowpart (Pmode, operands[3]);
5018   [(set_attr "type" "lea")
5019    (set_attr "mode" "SI")])
5021 (define_insn_and_split "*lea_general_2"
5022   [(set (match_operand 0 "register_operand" "=r")
5023         (plus (mult (match_operand 1 "index_register_operand" "l")
5024                     (match_operand 2 "const248_operand" "i"))
5025               (match_operand 3 "nonmemory_operand" "ri")))]
5026   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5027     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5028    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5029    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5030    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5031        || GET_MODE (operands[3]) == VOIDmode)"
5032   "#"
5033   "&& reload_completed"
5034   [(const_int 0)]
5036   rtx pat;
5037   operands[0] = gen_lowpart (SImode, operands[0]);
5038   operands[1] = gen_lowpart (Pmode, operands[1]);
5039   operands[3] = gen_lowpart (Pmode, operands[3]);
5040   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5041                       operands[3]);
5042   if (Pmode != SImode)
5043     pat = gen_rtx_SUBREG (SImode, pat, 0);
5044   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5045   DONE;
5047   [(set_attr "type" "lea")
5048    (set_attr "mode" "SI")])
5050 (define_insn_and_split "*lea_general_2_zext"
5051   [(set (match_operand:DI 0 "register_operand" "=r")
5052         (zero_extend:DI
5053           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5054                             (match_operand:SI 2 "const248_operand" "n"))
5055                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5056   "TARGET_64BIT"
5057   "#"
5058   "&& reload_completed"
5059   [(set (match_dup 0)
5060         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5061                                                      (match_dup 2))
5062                                             (match_dup 3)) 0)))]
5064   operands[1] = gen_lowpart (Pmode, operands[1]);
5065   operands[3] = gen_lowpart (Pmode, operands[3]);
5067   [(set_attr "type" "lea")
5068    (set_attr "mode" "SI")])
5070 (define_insn_and_split "*lea_general_3"
5071   [(set (match_operand 0 "register_operand" "=r")
5072         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5073                           (match_operand 2 "const248_operand" "i"))
5074                     (match_operand 3 "register_operand" "r"))
5075               (match_operand 4 "immediate_operand" "i")))]
5076   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5077     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5078    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5079    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5080    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5081   "#"
5082   "&& reload_completed"
5083   [(const_int 0)]
5085   rtx pat;
5086   operands[0] = gen_lowpart (SImode, operands[0]);
5087   operands[1] = gen_lowpart (Pmode, operands[1]);
5088   operands[3] = gen_lowpart (Pmode, operands[3]);
5089   operands[4] = gen_lowpart (Pmode, operands[4]);
5090   pat = gen_rtx_PLUS (Pmode,
5091                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5092                                                          operands[2]),
5093                                     operands[3]),
5094                       operands[4]);
5095   if (Pmode != SImode)
5096     pat = gen_rtx_SUBREG (SImode, pat, 0);
5097   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5098   DONE;
5100   [(set_attr "type" "lea")
5101    (set_attr "mode" "SI")])
5103 (define_insn_and_split "*lea_general_3_zext"
5104   [(set (match_operand:DI 0 "register_operand" "=r")
5105         (zero_extend:DI
5106           (plus:SI (plus:SI (mult:SI
5107                               (match_operand:SI 1 "index_register_operand" "l")
5108                               (match_operand:SI 2 "const248_operand" "n"))
5109                             (match_operand:SI 3 "register_operand" "r"))
5110                    (match_operand:SI 4 "immediate_operand" "i"))))]
5111   "TARGET_64BIT"
5112   "#"
5113   "&& reload_completed"
5114   [(set (match_dup 0)
5115         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5116                                                               (match_dup 2))
5117                                                      (match_dup 3))
5118                                             (match_dup 4)) 0)))]
5120   operands[1] = gen_lowpart (Pmode, operands[1]);
5121   operands[3] = gen_lowpart (Pmode, operands[3]);
5122   operands[4] = gen_lowpart (Pmode, operands[4]);
5124   [(set_attr "type" "lea")
5125    (set_attr "mode" "SI")])
5127 (define_insn "*adddi_1_rex64"
5128   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5129         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5130                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5131    (clobber (reg:CC FLAGS_REG))]
5132   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5134   switch (get_attr_type (insn))
5135     {
5136     case TYPE_LEA:
5137       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5138       return "lea{q}\t{%a2, %0|%0, %a2}";
5140     case TYPE_INCDEC:
5141       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5142       if (operands[2] == const1_rtx)
5143         return "inc{q}\t%0";
5144       else
5145         {
5146           gcc_assert (operands[2] == constm1_rtx);
5147           return "dec{q}\t%0";
5148         }
5150     default:
5151       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5153       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5154          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5155       if (CONST_INT_P (operands[2])
5156           /* Avoid overflows.  */
5157           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5158           && (INTVAL (operands[2]) == 128
5159               || (INTVAL (operands[2]) < 0
5160                   && INTVAL (operands[2]) != -128)))
5161         {
5162           operands[2] = GEN_INT (-INTVAL (operands[2]));
5163           return "sub{q}\t{%2, %0|%0, %2}";
5164         }
5165       return "add{q}\t{%2, %0|%0, %2}";
5166     }
5168   [(set (attr "type")
5169      (cond [(eq_attr "alternative" "2")
5170               (const_string "lea")
5171             ; Current assemblers are broken and do not allow @GOTOFF in
5172             ; ought but a memory context.
5173             (match_operand:DI 2 "pic_symbolic_operand" "")
5174               (const_string "lea")
5175             (match_operand:DI 2 "incdec_operand" "")
5176               (const_string "incdec")
5177            ]
5178            (const_string "alu")))
5179    (set_attr "mode" "DI")])
5181 ;; Convert lea to the lea pattern to avoid flags dependency.
5182 (define_split
5183   [(set (match_operand:DI 0 "register_operand" "")
5184         (plus:DI (match_operand:DI 1 "register_operand" "")
5185                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5186    (clobber (reg:CC FLAGS_REG))]
5187   "TARGET_64BIT && reload_completed
5188    && true_regnum (operands[0]) != true_regnum (operands[1])"
5189   [(set (match_dup 0)
5190         (plus:DI (match_dup 1)
5191                  (match_dup 2)))]
5192   "")
5194 (define_insn "*adddi_2_rex64"
5195   [(set (reg FLAGS_REG)
5196         (compare
5197           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5198                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5199           (const_int 0)))
5200    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5201         (plus:DI (match_dup 1) (match_dup 2)))]
5202   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5203    && ix86_binary_operator_ok (PLUS, DImode, operands)
5204    /* Current assemblers are broken and do not allow @GOTOFF in
5205       ought but a memory context.  */
5206    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5208   switch (get_attr_type (insn))
5209     {
5210     case TYPE_INCDEC:
5211       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5212       if (operands[2] == const1_rtx)
5213         return "inc{q}\t%0";
5214       else
5215         {
5216           gcc_assert (operands[2] == constm1_rtx);
5217           return "dec{q}\t%0";
5218         }
5220     default:
5221       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5222       /* ???? We ought to handle there the 32bit case too
5223          - do we need new constraint?  */
5224       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5225          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5226       if (CONST_INT_P (operands[2])
5227           /* Avoid overflows.  */
5228           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5229           && (INTVAL (operands[2]) == 128
5230               || (INTVAL (operands[2]) < 0
5231                   && INTVAL (operands[2]) != -128)))
5232         {
5233           operands[2] = GEN_INT (-INTVAL (operands[2]));
5234           return "sub{q}\t{%2, %0|%0, %2}";
5235         }
5236       return "add{q}\t{%2, %0|%0, %2}";
5237     }
5239   [(set (attr "type")
5240      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5241         (const_string "incdec")
5242         (const_string "alu")))
5243    (set_attr "mode" "DI")])
5245 (define_insn "*adddi_3_rex64"
5246   [(set (reg FLAGS_REG)
5247         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5248                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5249    (clobber (match_scratch:DI 0 "=r"))]
5250   "TARGET_64BIT
5251    && ix86_match_ccmode (insn, CCZmode)
5252    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5253    /* Current assemblers are broken and do not allow @GOTOFF in
5254       ought but a memory context.  */
5255    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5257   switch (get_attr_type (insn))
5258     {
5259     case TYPE_INCDEC:
5260       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5261       if (operands[2] == const1_rtx)
5262         return "inc{q}\t%0";
5263       else
5264         {
5265           gcc_assert (operands[2] == constm1_rtx);
5266           return "dec{q}\t%0";
5267         }
5269     default:
5270       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5271       /* ???? We ought to handle there the 32bit case too
5272          - do we need new constraint?  */
5273       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5274          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5275       if (CONST_INT_P (operands[2])
5276           /* Avoid overflows.  */
5277           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5278           && (INTVAL (operands[2]) == 128
5279               || (INTVAL (operands[2]) < 0
5280                   && INTVAL (operands[2]) != -128)))
5281         {
5282           operands[2] = GEN_INT (-INTVAL (operands[2]));
5283           return "sub{q}\t{%2, %0|%0, %2}";
5284         }
5285       return "add{q}\t{%2, %0|%0, %2}";
5286     }
5288   [(set (attr "type")
5289      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5290         (const_string "incdec")
5291         (const_string "alu")))
5292    (set_attr "mode" "DI")])
5294 ; For comparisons against 1, -1 and 128, we may generate better code
5295 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5296 ; is matched then.  We can't accept general immediate, because for
5297 ; case of overflows,  the result is messed up.
5298 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5299 ; when negated.
5300 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5301 ; only for comparisons not depending on it.
5302 (define_insn "*adddi_4_rex64"
5303   [(set (reg FLAGS_REG)
5304         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5305                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5306    (clobber (match_scratch:DI 0 "=rm"))]
5307   "TARGET_64BIT
5308    &&  ix86_match_ccmode (insn, CCGCmode)"
5310   switch (get_attr_type (insn))
5311     {
5312     case TYPE_INCDEC:
5313       if (operands[2] == constm1_rtx)
5314         return "inc{q}\t%0";
5315       else
5316         {
5317           gcc_assert (operands[2] == const1_rtx);
5318           return "dec{q}\t%0";
5319         }
5321     default:
5322       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5323       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5324          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5325       if ((INTVAL (operands[2]) == -128
5326            || (INTVAL (operands[2]) > 0
5327                && INTVAL (operands[2]) != 128))
5328           /* Avoid overflows.  */
5329           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5330         return "sub{q}\t{%2, %0|%0, %2}";
5331       operands[2] = GEN_INT (-INTVAL (operands[2]));
5332       return "add{q}\t{%2, %0|%0, %2}";
5333     }
5335   [(set (attr "type")
5336      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5337         (const_string "incdec")
5338         (const_string "alu")))
5339    (set_attr "mode" "DI")])
5341 (define_insn "*adddi_5_rex64"
5342   [(set (reg FLAGS_REG)
5343         (compare
5344           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5345                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5346           (const_int 0)))
5347    (clobber (match_scratch:DI 0 "=r"))]
5348   "TARGET_64BIT
5349    && ix86_match_ccmode (insn, CCGOCmode)
5350    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5351    /* Current assemblers are broken and do not allow @GOTOFF in
5352       ought but a memory context.  */
5353    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5355   switch (get_attr_type (insn))
5356     {
5357     case TYPE_INCDEC:
5358       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5359       if (operands[2] == const1_rtx)
5360         return "inc{q}\t%0";
5361       else
5362         {
5363           gcc_assert (operands[2] == constm1_rtx);
5364           return "dec{q}\t%0";
5365         }
5367     default:
5368       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5369       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5370          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5371       if (CONST_INT_P (operands[2])
5372           /* Avoid overflows.  */
5373           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5374           && (INTVAL (operands[2]) == 128
5375               || (INTVAL (operands[2]) < 0
5376                   && INTVAL (operands[2]) != -128)))
5377         {
5378           operands[2] = GEN_INT (-INTVAL (operands[2]));
5379           return "sub{q}\t{%2, %0|%0, %2}";
5380         }
5381       return "add{q}\t{%2, %0|%0, %2}";
5382     }
5384   [(set (attr "type")
5385      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5386         (const_string "incdec")
5387         (const_string "alu")))
5388    (set_attr "mode" "DI")])
5391 (define_insn "*addsi_1"
5392   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5393         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5394                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5395    (clobber (reg:CC FLAGS_REG))]
5396   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5398   switch (get_attr_type (insn))
5399     {
5400     case TYPE_LEA:
5401       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5402       return "lea{l}\t{%a2, %0|%0, %a2}";
5404     case TYPE_INCDEC:
5405       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5406       if (operands[2] == const1_rtx)
5407         return "inc{l}\t%0";
5408       else
5409         {
5410           gcc_assert (operands[2] == constm1_rtx);
5411           return "dec{l}\t%0";
5412         }
5414     default:
5415       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5417       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5418          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5419       if (CONST_INT_P (operands[2])
5420           && (INTVAL (operands[2]) == 128
5421               || (INTVAL (operands[2]) < 0
5422                   && INTVAL (operands[2]) != -128)))
5423         {
5424           operands[2] = GEN_INT (-INTVAL (operands[2]));
5425           return "sub{l}\t{%2, %0|%0, %2}";
5426         }
5427       return "add{l}\t{%2, %0|%0, %2}";
5428     }
5430   [(set (attr "type")
5431      (cond [(eq_attr "alternative" "2")
5432               (const_string "lea")
5433             ; Current assemblers are broken and do not allow @GOTOFF in
5434             ; ought but a memory context.
5435             (match_operand:SI 2 "pic_symbolic_operand" "")
5436               (const_string "lea")
5437             (match_operand:SI 2 "incdec_operand" "")
5438               (const_string "incdec")
5439            ]
5440            (const_string "alu")))
5441    (set_attr "mode" "SI")])
5443 ;; Convert lea to the lea pattern to avoid flags dependency.
5444 (define_split
5445   [(set (match_operand 0 "register_operand" "")
5446         (plus (match_operand 1 "register_operand" "")
5447               (match_operand 2 "nonmemory_operand" "")))
5448    (clobber (reg:CC FLAGS_REG))]
5449   "reload_completed
5450    && true_regnum (operands[0]) != true_regnum (operands[1])"
5451   [(const_int 0)]
5453   rtx pat;
5454   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5455      may confuse gen_lowpart.  */
5456   if (GET_MODE (operands[0]) != Pmode)
5457     {
5458       operands[1] = gen_lowpart (Pmode, operands[1]);
5459       operands[2] = gen_lowpart (Pmode, operands[2]);
5460     }
5461   operands[0] = gen_lowpart (SImode, operands[0]);
5462   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5463   if (Pmode != SImode)
5464     pat = gen_rtx_SUBREG (SImode, pat, 0);
5465   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5466   DONE;
5469 ;; It may seem that nonimmediate operand is proper one for operand 1.
5470 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5471 ;; we take care in ix86_binary_operator_ok to not allow two memory
5472 ;; operands so proper swapping will be done in reload.  This allow
5473 ;; patterns constructed from addsi_1 to match.
5474 (define_insn "addsi_1_zext"
5475   [(set (match_operand:DI 0 "register_operand" "=r,r")
5476         (zero_extend:DI
5477           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5478                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5479    (clobber (reg:CC FLAGS_REG))]
5480   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5482   switch (get_attr_type (insn))
5483     {
5484     case TYPE_LEA:
5485       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5486       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5488     case TYPE_INCDEC:
5489       if (operands[2] == const1_rtx)
5490         return "inc{l}\t%k0";
5491       else
5492         {
5493           gcc_assert (operands[2] == constm1_rtx);
5494           return "dec{l}\t%k0";
5495         }
5497     default:
5498       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5499          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5500       if (CONST_INT_P (operands[2])
5501           && (INTVAL (operands[2]) == 128
5502               || (INTVAL (operands[2]) < 0
5503                   && INTVAL (operands[2]) != -128)))
5504         {
5505           operands[2] = GEN_INT (-INTVAL (operands[2]));
5506           return "sub{l}\t{%2, %k0|%k0, %2}";
5507         }
5508       return "add{l}\t{%2, %k0|%k0, %2}";
5509     }
5511   [(set (attr "type")
5512      (cond [(eq_attr "alternative" "1")
5513               (const_string "lea")
5514             ; Current assemblers are broken and do not allow @GOTOFF in
5515             ; ought but a memory context.
5516             (match_operand:SI 2 "pic_symbolic_operand" "")
5517               (const_string "lea")
5518             (match_operand:SI 2 "incdec_operand" "")
5519               (const_string "incdec")
5520            ]
5521            (const_string "alu")))
5522    (set_attr "mode" "SI")])
5524 ;; Convert lea to the lea pattern to avoid flags dependency.
5525 (define_split
5526   [(set (match_operand:DI 0 "register_operand" "")
5527         (zero_extend:DI
5528           (plus:SI (match_operand:SI 1 "register_operand" "")
5529                    (match_operand:SI 2 "nonmemory_operand" ""))))
5530    (clobber (reg:CC FLAGS_REG))]
5531   "TARGET_64BIT && reload_completed
5532    && true_regnum (operands[0]) != true_regnum (operands[1])"
5533   [(set (match_dup 0)
5534         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5536   operands[1] = gen_lowpart (Pmode, operands[1]);
5537   operands[2] = gen_lowpart (Pmode, operands[2]);
5540 (define_insn "*addsi_2"
5541   [(set (reg FLAGS_REG)
5542         (compare
5543           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5544                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5545           (const_int 0)))
5546    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5547         (plus:SI (match_dup 1) (match_dup 2)))]
5548   "ix86_match_ccmode (insn, CCGOCmode)
5549    && ix86_binary_operator_ok (PLUS, SImode, operands)
5550    /* Current assemblers are broken and do not allow @GOTOFF in
5551       ought but a memory context.  */
5552    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5554   switch (get_attr_type (insn))
5555     {
5556     case TYPE_INCDEC:
5557       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5558       if (operands[2] == const1_rtx)
5559         return "inc{l}\t%0";
5560       else
5561         {
5562           gcc_assert (operands[2] == constm1_rtx);
5563           return "dec{l}\t%0";
5564         }
5566     default:
5567       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5568       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5569          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5570       if (CONST_INT_P (operands[2])
5571           && (INTVAL (operands[2]) == 128
5572               || (INTVAL (operands[2]) < 0
5573                   && INTVAL (operands[2]) != -128)))
5574         {
5575           operands[2] = GEN_INT (-INTVAL (operands[2]));
5576           return "sub{l}\t{%2, %0|%0, %2}";
5577         }
5578       return "add{l}\t{%2, %0|%0, %2}";
5579     }
5581   [(set (attr "type")
5582      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5583         (const_string "incdec")
5584         (const_string "alu")))
5585    (set_attr "mode" "SI")])
5587 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5588 (define_insn "*addsi_2_zext"
5589   [(set (reg FLAGS_REG)
5590         (compare
5591           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5592                    (match_operand:SI 2 "general_operand" "rmni"))
5593           (const_int 0)))
5594    (set (match_operand:DI 0 "register_operand" "=r")
5595         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5596   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5597    && ix86_binary_operator_ok (PLUS, SImode, operands)
5598    /* Current assemblers are broken and do not allow @GOTOFF in
5599       ought but a memory context.  */
5600    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5602   switch (get_attr_type (insn))
5603     {
5604     case TYPE_INCDEC:
5605       if (operands[2] == const1_rtx)
5606         return "inc{l}\t%k0";
5607       else
5608         {
5609           gcc_assert (operands[2] == constm1_rtx);
5610           return "dec{l}\t%k0";
5611         }
5613     default:
5614       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5615          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5616       if (CONST_INT_P (operands[2])
5617           && (INTVAL (operands[2]) == 128
5618               || (INTVAL (operands[2]) < 0
5619                   && INTVAL (operands[2]) != -128)))
5620         {
5621           operands[2] = GEN_INT (-INTVAL (operands[2]));
5622           return "sub{l}\t{%2, %k0|%k0, %2}";
5623         }
5624       return "add{l}\t{%2, %k0|%k0, %2}";
5625     }
5627   [(set (attr "type")
5628      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5629         (const_string "incdec")
5630         (const_string "alu")))
5631    (set_attr "mode" "SI")])
5633 (define_insn "*addsi_3"
5634   [(set (reg FLAGS_REG)
5635         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5636                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5637    (clobber (match_scratch:SI 0 "=r"))]
5638   "ix86_match_ccmode (insn, CCZmode)
5639    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5640    /* Current assemblers are broken and do not allow @GOTOFF in
5641       ought but a memory context.  */
5642    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5644   switch (get_attr_type (insn))
5645     {
5646     case TYPE_INCDEC:
5647       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5648       if (operands[2] == const1_rtx)
5649         return "inc{l}\t%0";
5650       else
5651         {
5652           gcc_assert (operands[2] == constm1_rtx);
5653           return "dec{l}\t%0";
5654         }
5656     default:
5657       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5659          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5660       if (CONST_INT_P (operands[2])
5661           && (INTVAL (operands[2]) == 128
5662               || (INTVAL (operands[2]) < 0
5663                   && INTVAL (operands[2]) != -128)))
5664         {
5665           operands[2] = GEN_INT (-INTVAL (operands[2]));
5666           return "sub{l}\t{%2, %0|%0, %2}";
5667         }
5668       return "add{l}\t{%2, %0|%0, %2}";
5669     }
5671   [(set (attr "type")
5672      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5673         (const_string "incdec")
5674         (const_string "alu")))
5675    (set_attr "mode" "SI")])
5677 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5678 (define_insn "*addsi_3_zext"
5679   [(set (reg FLAGS_REG)
5680         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5681                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5682    (set (match_operand:DI 0 "register_operand" "=r")
5683         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5684   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5685    && ix86_binary_operator_ok (PLUS, SImode, operands)
5686    /* Current assemblers are broken and do not allow @GOTOFF in
5687       ought but a memory context.  */
5688    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5690   switch (get_attr_type (insn))
5691     {
5692     case TYPE_INCDEC:
5693       if (operands[2] == const1_rtx)
5694         return "inc{l}\t%k0";
5695       else
5696         {
5697           gcc_assert (operands[2] == constm1_rtx);
5698           return "dec{l}\t%k0";
5699         }
5701     default:
5702       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5703          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5704       if (CONST_INT_P (operands[2])
5705           && (INTVAL (operands[2]) == 128
5706               || (INTVAL (operands[2]) < 0
5707                   && INTVAL (operands[2]) != -128)))
5708         {
5709           operands[2] = GEN_INT (-INTVAL (operands[2]));
5710           return "sub{l}\t{%2, %k0|%k0, %2}";
5711         }
5712       return "add{l}\t{%2, %k0|%k0, %2}";
5713     }
5715   [(set (attr "type")
5716      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5717         (const_string "incdec")
5718         (const_string "alu")))
5719    (set_attr "mode" "SI")])
5721 ; For comparisons against 1, -1 and 128, we may generate better code
5722 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5723 ; is matched then.  We can't accept general immediate, because for
5724 ; case of overflows,  the result is messed up.
5725 ; This pattern also don't hold of 0x80000000, since the value overflows
5726 ; when negated.
5727 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5728 ; only for comparisons not depending on it.
5729 (define_insn "*addsi_4"
5730   [(set (reg FLAGS_REG)
5731         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5732                  (match_operand:SI 2 "const_int_operand" "n")))
5733    (clobber (match_scratch:SI 0 "=rm"))]
5734   "ix86_match_ccmode (insn, CCGCmode)
5735    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5737   switch (get_attr_type (insn))
5738     {
5739     case TYPE_INCDEC:
5740       if (operands[2] == constm1_rtx)
5741         return "inc{l}\t%0";
5742       else
5743         {
5744           gcc_assert (operands[2] == const1_rtx);
5745           return "dec{l}\t%0";
5746         }
5748     default:
5749       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5750       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5751          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5752       if ((INTVAL (operands[2]) == -128
5753            || (INTVAL (operands[2]) > 0
5754                && INTVAL (operands[2]) != 128)))
5755         return "sub{l}\t{%2, %0|%0, %2}";
5756       operands[2] = GEN_INT (-INTVAL (operands[2]));
5757       return "add{l}\t{%2, %0|%0, %2}";
5758     }
5760   [(set (attr "type")
5761      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5762         (const_string "incdec")
5763         (const_string "alu")))
5764    (set_attr "mode" "SI")])
5766 (define_insn "*addsi_5"
5767   [(set (reg FLAGS_REG)
5768         (compare
5769           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5770                    (match_operand:SI 2 "general_operand" "rmni"))
5771           (const_int 0)))
5772    (clobber (match_scratch:SI 0 "=r"))]
5773   "ix86_match_ccmode (insn, CCGOCmode)
5774    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5775    /* Current assemblers are broken and do not allow @GOTOFF in
5776       ought but a memory context.  */
5777    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5779   switch (get_attr_type (insn))
5780     {
5781     case TYPE_INCDEC:
5782       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5783       if (operands[2] == const1_rtx)
5784         return "inc{l}\t%0";
5785       else
5786         {
5787           gcc_assert (operands[2] == constm1_rtx);
5788           return "dec{l}\t%0";
5789         }
5791     default:
5792       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5793       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5794          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5795       if (CONST_INT_P (operands[2])
5796           && (INTVAL (operands[2]) == 128
5797               || (INTVAL (operands[2]) < 0
5798                   && INTVAL (operands[2]) != -128)))
5799         {
5800           operands[2] = GEN_INT (-INTVAL (operands[2]));
5801           return "sub{l}\t{%2, %0|%0, %2}";
5802         }
5803       return "add{l}\t{%2, %0|%0, %2}";
5804     }
5806   [(set (attr "type")
5807      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5808         (const_string "incdec")
5809         (const_string "alu")))
5810    (set_attr "mode" "SI")])
5812 (define_expand "addhi3"
5813   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5814                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5815                             (match_operand:HI 2 "general_operand" "")))
5816               (clobber (reg:CC FLAGS_REG))])]
5817   "TARGET_HIMODE_MATH"
5818   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5820 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5821 ;; type optimizations enabled by define-splits.  This is not important
5822 ;; for PII, and in fact harmful because of partial register stalls.
5824 (define_insn "*addhi_1_lea"
5825   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5826         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5827                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5828    (clobber (reg:CC FLAGS_REG))]
5829   "!TARGET_PARTIAL_REG_STALL
5830    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5832   switch (get_attr_type (insn))
5833     {
5834     case TYPE_LEA:
5835       return "#";
5836     case TYPE_INCDEC:
5837       if (operands[2] == const1_rtx)
5838         return "inc{w}\t%0";
5839       else
5840         {
5841           gcc_assert (operands[2] == constm1_rtx);
5842           return "dec{w}\t%0";
5843         }
5845     default:
5846       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5847          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5848       if (CONST_INT_P (operands[2])
5849           && (INTVAL (operands[2]) == 128
5850               || (INTVAL (operands[2]) < 0
5851                   && INTVAL (operands[2]) != -128)))
5852         {
5853           operands[2] = GEN_INT (-INTVAL (operands[2]));
5854           return "sub{w}\t{%2, %0|%0, %2}";
5855         }
5856       return "add{w}\t{%2, %0|%0, %2}";
5857     }
5859   [(set (attr "type")
5860      (if_then_else (eq_attr "alternative" "2")
5861         (const_string "lea")
5862         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5863            (const_string "incdec")
5864            (const_string "alu"))))
5865    (set_attr "mode" "HI,HI,SI")])
5867 (define_insn "*addhi_1"
5868   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5869         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5870                  (match_operand:HI 2 "general_operand" "ri,rm")))
5871    (clobber (reg:CC FLAGS_REG))]
5872   "TARGET_PARTIAL_REG_STALL
5873    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5875   switch (get_attr_type (insn))
5876     {
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 (match_operand:HI 2 "incdec_operand" "")
5902         (const_string "incdec")
5903         (const_string "alu")))
5904    (set_attr "mode" "HI")])
5906 (define_insn "*addhi_2"
5907   [(set (reg FLAGS_REG)
5908         (compare
5909           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5910                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5911           (const_int 0)))
5912    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5913         (plus:HI (match_dup 1) (match_dup 2)))]
5914   "ix86_match_ccmode (insn, CCGOCmode)
5915    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5917   switch (get_attr_type (insn))
5918     {
5919     case TYPE_INCDEC:
5920       if (operands[2] == const1_rtx)
5921         return "inc{w}\t%0";
5922       else
5923         {
5924           gcc_assert (operands[2] == constm1_rtx);
5925           return "dec{w}\t%0";
5926         }
5928     default:
5929       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5930          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5931       if (CONST_INT_P (operands[2])
5932           && (INTVAL (operands[2]) == 128
5933               || (INTVAL (operands[2]) < 0
5934                   && INTVAL (operands[2]) != -128)))
5935         {
5936           operands[2] = GEN_INT (-INTVAL (operands[2]));
5937           return "sub{w}\t{%2, %0|%0, %2}";
5938         }
5939       return "add{w}\t{%2, %0|%0, %2}";
5940     }
5942   [(set (attr "type")
5943      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5944         (const_string "incdec")
5945         (const_string "alu")))
5946    (set_attr "mode" "HI")])
5948 (define_insn "*addhi_3"
5949   [(set (reg FLAGS_REG)
5950         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5951                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5952    (clobber (match_scratch:HI 0 "=r"))]
5953   "ix86_match_ccmode (insn, CCZmode)
5954    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5956   switch (get_attr_type (insn))
5957     {
5958     case TYPE_INCDEC:
5959       if (operands[2] == const1_rtx)
5960         return "inc{w}\t%0";
5961       else
5962         {
5963           gcc_assert (operands[2] == constm1_rtx);
5964           return "dec{w}\t%0";
5965         }
5967     default:
5968       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5969          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5970       if (CONST_INT_P (operands[2])
5971           && (INTVAL (operands[2]) == 128
5972               || (INTVAL (operands[2]) < 0
5973                   && INTVAL (operands[2]) != -128)))
5974         {
5975           operands[2] = GEN_INT (-INTVAL (operands[2]));
5976           return "sub{w}\t{%2, %0|%0, %2}";
5977         }
5978       return "add{w}\t{%2, %0|%0, %2}";
5979     }
5981   [(set (attr "type")
5982      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5983         (const_string "incdec")
5984         (const_string "alu")))
5985    (set_attr "mode" "HI")])
5987 ; See comments above addsi_4 for details.
5988 (define_insn "*addhi_4"
5989   [(set (reg FLAGS_REG)
5990         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5991                  (match_operand:HI 2 "const_int_operand" "n")))
5992    (clobber (match_scratch:HI 0 "=rm"))]
5993   "ix86_match_ccmode (insn, CCGCmode)
5994    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5996   switch (get_attr_type (insn))
5997     {
5998     case TYPE_INCDEC:
5999       if (operands[2] == constm1_rtx)
6000         return "inc{w}\t%0";
6001       else
6002         {
6003           gcc_assert (operands[2] == const1_rtx);
6004           return "dec{w}\t%0";
6005         }
6007     default:
6008       gcc_assert (rtx_equal_p (operands[0], operands[1]));
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 ((INTVAL (operands[2]) == -128
6012            || (INTVAL (operands[2]) > 0
6013                && INTVAL (operands[2]) != 128)))
6014         return "sub{w}\t{%2, %0|%0, %2}";
6015       operands[2] = GEN_INT (-INTVAL (operands[2]));
6016       return "add{w}\t{%2, %0|%0, %2}";
6017     }
6019   [(set (attr "type")
6020      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6021         (const_string "incdec")
6022         (const_string "alu")))
6023    (set_attr "mode" "SI")])
6026 (define_insn "*addhi_5"
6027   [(set (reg FLAGS_REG)
6028         (compare
6029           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6030                    (match_operand:HI 2 "general_operand" "rmni"))
6031           (const_int 0)))
6032    (clobber (match_scratch:HI 0 "=r"))]
6033   "ix86_match_ccmode (insn, CCGOCmode)
6034    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6036   switch (get_attr_type (insn))
6037     {
6038     case TYPE_INCDEC:
6039       if (operands[2] == const1_rtx)
6040         return "inc{w}\t%0";
6041       else
6042         {
6043           gcc_assert (operands[2] == constm1_rtx);
6044           return "dec{w}\t%0";
6045         }
6047     default:
6048       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6049          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6050       if (CONST_INT_P (operands[2])
6051           && (INTVAL (operands[2]) == 128
6052               || (INTVAL (operands[2]) < 0
6053                   && INTVAL (operands[2]) != -128)))
6054         {
6055           operands[2] = GEN_INT (-INTVAL (operands[2]));
6056           return "sub{w}\t{%2, %0|%0, %2}";
6057         }
6058       return "add{w}\t{%2, %0|%0, %2}";
6059     }
6061   [(set (attr "type")
6062      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6063         (const_string "incdec")
6064         (const_string "alu")))
6065    (set_attr "mode" "HI")])
6067 (define_expand "addqi3"
6068   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6069                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6070                             (match_operand:QI 2 "general_operand" "")))
6071               (clobber (reg:CC FLAGS_REG))])]
6072   "TARGET_QIMODE_MATH"
6073   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6075 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6076 (define_insn "*addqi_1_lea"
6077   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6078         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6079                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6080    (clobber (reg:CC FLAGS_REG))]
6081   "!TARGET_PARTIAL_REG_STALL
6082    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6084   int widen = (which_alternative == 2);
6085   switch (get_attr_type (insn))
6086     {
6087     case TYPE_LEA:
6088       return "#";
6089     case TYPE_INCDEC:
6090       if (operands[2] == const1_rtx)
6091         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6092       else
6093         {
6094           gcc_assert (operands[2] == constm1_rtx);
6095           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6096         }
6098     default:
6099       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6100          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6101       if (CONST_INT_P (operands[2])
6102           && (INTVAL (operands[2]) == 128
6103               || (INTVAL (operands[2]) < 0
6104                   && INTVAL (operands[2]) != -128)))
6105         {
6106           operands[2] = GEN_INT (-INTVAL (operands[2]));
6107           if (widen)
6108             return "sub{l}\t{%2, %k0|%k0, %2}";
6109           else
6110             return "sub{b}\t{%2, %0|%0, %2}";
6111         }
6112       if (widen)
6113         return "add{l}\t{%k2, %k0|%k0, %k2}";
6114       else
6115         return "add{b}\t{%2, %0|%0, %2}";
6116     }
6118   [(set (attr "type")
6119      (if_then_else (eq_attr "alternative" "3")
6120         (const_string "lea")
6121         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6122            (const_string "incdec")
6123            (const_string "alu"))))
6124    (set_attr "mode" "QI,QI,SI,SI")])
6126 (define_insn "*addqi_1"
6127   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6128         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6129                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6130    (clobber (reg:CC FLAGS_REG))]
6131   "TARGET_PARTIAL_REG_STALL
6132    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6134   int widen = (which_alternative == 2);
6135   switch (get_attr_type (insn))
6136     {
6137     case TYPE_INCDEC:
6138       if (operands[2] == const1_rtx)
6139         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6140       else
6141         {
6142           gcc_assert (operands[2] == constm1_rtx);
6143           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6144         }
6146     default:
6147       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6148          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6149       if (CONST_INT_P (operands[2])
6150           && (INTVAL (operands[2]) == 128
6151               || (INTVAL (operands[2]) < 0
6152                   && INTVAL (operands[2]) != -128)))
6153         {
6154           operands[2] = GEN_INT (-INTVAL (operands[2]));
6155           if (widen)
6156             return "sub{l}\t{%2, %k0|%k0, %2}";
6157           else
6158             return "sub{b}\t{%2, %0|%0, %2}";
6159         }
6160       if (widen)
6161         return "add{l}\t{%k2, %k0|%k0, %k2}";
6162       else
6163         return "add{b}\t{%2, %0|%0, %2}";
6164     }
6166   [(set (attr "type")
6167      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6168         (const_string "incdec")
6169         (const_string "alu")))
6170    (set_attr "mode" "QI,QI,SI")])
6172 (define_insn "*addqi_1_slp"
6173   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6174         (plus:QI (match_dup 0)
6175                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6176    (clobber (reg:CC FLAGS_REG))]
6177   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6178    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6180   switch (get_attr_type (insn))
6181     {
6182     case TYPE_INCDEC:
6183       if (operands[1] == const1_rtx)
6184         return "inc{b}\t%0";
6185       else
6186         {
6187           gcc_assert (operands[1] == constm1_rtx);
6188           return "dec{b}\t%0";
6189         }
6191     default:
6192       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6193       if (CONST_INT_P (operands[1])
6194           && INTVAL (operands[1]) < 0)
6195         {
6196           operands[1] = GEN_INT (-INTVAL (operands[1]));
6197           return "sub{b}\t{%1, %0|%0, %1}";
6198         }
6199       return "add{b}\t{%1, %0|%0, %1}";
6200     }
6202   [(set (attr "type")
6203      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6204         (const_string "incdec")
6205         (const_string "alu1")))
6206    (set (attr "memory")
6207      (if_then_else (match_operand 1 "memory_operand" "")
6208         (const_string "load")
6209         (const_string "none")))
6210    (set_attr "mode" "QI")])
6212 (define_insn "*addqi_2"
6213   [(set (reg FLAGS_REG)
6214         (compare
6215           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6216                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6217           (const_int 0)))
6218    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6219         (plus:QI (match_dup 1) (match_dup 2)))]
6220   "ix86_match_ccmode (insn, CCGOCmode)
6221    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6223   switch (get_attr_type (insn))
6224     {
6225     case TYPE_INCDEC:
6226       if (operands[2] == const1_rtx)
6227         return "inc{b}\t%0";
6228       else
6229         {
6230           gcc_assert (operands[2] == constm1_rtx
6231                       || (CONST_INT_P (operands[2])
6232                           && INTVAL (operands[2]) == 255));
6233           return "dec{b}\t%0";
6234         }
6236     default:
6237       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6238       if (CONST_INT_P (operands[2])
6239           && INTVAL (operands[2]) < 0)
6240         {
6241           operands[2] = GEN_INT (-INTVAL (operands[2]));
6242           return "sub{b}\t{%2, %0|%0, %2}";
6243         }
6244       return "add{b}\t{%2, %0|%0, %2}";
6245     }
6247   [(set (attr "type")
6248      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6249         (const_string "incdec")
6250         (const_string "alu")))
6251    (set_attr "mode" "QI")])
6253 (define_insn "*addqi_3"
6254   [(set (reg FLAGS_REG)
6255         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6256                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6257    (clobber (match_scratch:QI 0 "=q"))]
6258   "ix86_match_ccmode (insn, CCZmode)
6259    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6261   switch (get_attr_type (insn))
6262     {
6263     case TYPE_INCDEC:
6264       if (operands[2] == const1_rtx)
6265         return "inc{b}\t%0";
6266       else
6267         {
6268           gcc_assert (operands[2] == constm1_rtx
6269                       || (CONST_INT_P (operands[2])
6270                           && INTVAL (operands[2]) == 255));
6271           return "dec{b}\t%0";
6272         }
6274     default:
6275       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6276       if (CONST_INT_P (operands[2])
6277           && INTVAL (operands[2]) < 0)
6278         {
6279           operands[2] = GEN_INT (-INTVAL (operands[2]));
6280           return "sub{b}\t{%2, %0|%0, %2}";
6281         }
6282       return "add{b}\t{%2, %0|%0, %2}";
6283     }
6285   [(set (attr "type")
6286      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6287         (const_string "incdec")
6288         (const_string "alu")))
6289    (set_attr "mode" "QI")])
6291 ; See comments above addsi_4 for details.
6292 (define_insn "*addqi_4"
6293   [(set (reg FLAGS_REG)
6294         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6295                  (match_operand:QI 2 "const_int_operand" "n")))
6296    (clobber (match_scratch:QI 0 "=qm"))]
6297   "ix86_match_ccmode (insn, CCGCmode)
6298    && (INTVAL (operands[2]) & 0xff) != 0x80"
6300   switch (get_attr_type (insn))
6301     {
6302     case TYPE_INCDEC:
6303       if (operands[2] == constm1_rtx
6304           || (CONST_INT_P (operands[2])
6305               && INTVAL (operands[2]) == 255))
6306         return "inc{b}\t%0";
6307       else
6308         {
6309           gcc_assert (operands[2] == const1_rtx);
6310           return "dec{b}\t%0";
6311         }
6313     default:
6314       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6315       if (INTVAL (operands[2]) < 0)
6316         {
6317           operands[2] = GEN_INT (-INTVAL (operands[2]));
6318           return "add{b}\t{%2, %0|%0, %2}";
6319         }
6320       return "sub{b}\t{%2, %0|%0, %2}";
6321     }
6323   [(set (attr "type")
6324      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6325         (const_string "incdec")
6326         (const_string "alu")))
6327    (set_attr "mode" "QI")])
6330 (define_insn "*addqi_5"
6331   [(set (reg FLAGS_REG)
6332         (compare
6333           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6334                    (match_operand:QI 2 "general_operand" "qmni"))
6335           (const_int 0)))
6336    (clobber (match_scratch:QI 0 "=q"))]
6337   "ix86_match_ccmode (insn, CCGOCmode)
6338    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6340   switch (get_attr_type (insn))
6341     {
6342     case TYPE_INCDEC:
6343       if (operands[2] == const1_rtx)
6344         return "inc{b}\t%0";
6345       else
6346         {
6347           gcc_assert (operands[2] == constm1_rtx
6348                       || (CONST_INT_P (operands[2])
6349                           && INTVAL (operands[2]) == 255));
6350           return "dec{b}\t%0";
6351         }
6353     default:
6354       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6355       if (CONST_INT_P (operands[2])
6356           && INTVAL (operands[2]) < 0)
6357         {
6358           operands[2] = GEN_INT (-INTVAL (operands[2]));
6359           return "sub{b}\t{%2, %0|%0, %2}";
6360         }
6361       return "add{b}\t{%2, %0|%0, %2}";
6362     }
6364   [(set (attr "type")
6365      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6366         (const_string "incdec")
6367         (const_string "alu")))
6368    (set_attr "mode" "QI")])
6371 (define_insn "addqi_ext_1"
6372   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6373                          (const_int 8)
6374                          (const_int 8))
6375         (plus:SI
6376           (zero_extract:SI
6377             (match_operand 1 "ext_register_operand" "0")
6378             (const_int 8)
6379             (const_int 8))
6380           (match_operand:QI 2 "general_operand" "Qmn")))
6381    (clobber (reg:CC FLAGS_REG))]
6382   "!TARGET_64BIT"
6384   switch (get_attr_type (insn))
6385     {
6386     case TYPE_INCDEC:
6387       if (operands[2] == const1_rtx)
6388         return "inc{b}\t%h0";
6389       else
6390         {
6391           gcc_assert (operands[2] == constm1_rtx
6392                       || (CONST_INT_P (operands[2])
6393                           && INTVAL (operands[2]) == 255));
6394           return "dec{b}\t%h0";
6395         }
6397     default:
6398       return "add{b}\t{%2, %h0|%h0, %2}";
6399     }
6401   [(set (attr "type")
6402      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6403         (const_string "incdec")
6404         (const_string "alu")))
6405    (set_attr "mode" "QI")])
6407 (define_insn "*addqi_ext_1_rex64"
6408   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6409                          (const_int 8)
6410                          (const_int 8))
6411         (plus:SI
6412           (zero_extract:SI
6413             (match_operand 1 "ext_register_operand" "0")
6414             (const_int 8)
6415             (const_int 8))
6416           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6417    (clobber (reg:CC FLAGS_REG))]
6418   "TARGET_64BIT"
6420   switch (get_attr_type (insn))
6421     {
6422     case TYPE_INCDEC:
6423       if (operands[2] == const1_rtx)
6424         return "inc{b}\t%h0";
6425       else
6426         {
6427           gcc_assert (operands[2] == constm1_rtx
6428                       || (CONST_INT_P (operands[2])
6429                           && INTVAL (operands[2]) == 255));
6430           return "dec{b}\t%h0";
6431         }
6433     default:
6434       return "add{b}\t{%2, %h0|%h0, %2}";
6435     }
6437   [(set (attr "type")
6438      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6439         (const_string "incdec")
6440         (const_string "alu")))
6441    (set_attr "mode" "QI")])
6443 (define_insn "*addqi_ext_2"
6444   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6445                          (const_int 8)
6446                          (const_int 8))
6447         (plus:SI
6448           (zero_extract:SI
6449             (match_operand 1 "ext_register_operand" "%0")
6450             (const_int 8)
6451             (const_int 8))
6452           (zero_extract:SI
6453             (match_operand 2 "ext_register_operand" "Q")
6454             (const_int 8)
6455             (const_int 8))))
6456    (clobber (reg:CC FLAGS_REG))]
6457   ""
6458   "add{b}\t{%h2, %h0|%h0, %h2}"
6459   [(set_attr "type" "alu")
6460    (set_attr "mode" "QI")])
6462 ;; The patterns that match these are at the end of this file.
6464 (define_expand "addxf3"
6465   [(set (match_operand:XF 0 "register_operand" "")
6466         (plus:XF (match_operand:XF 1 "register_operand" "")
6467                  (match_operand:XF 2 "register_operand" "")))]
6468   "TARGET_80387"
6469   "")
6471 (define_expand "adddf3"
6472   [(set (match_operand:DF 0 "register_operand" "")
6473         (plus:DF (match_operand:DF 1 "register_operand" "")
6474                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6475   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6476   "")
6478 (define_expand "addsf3"
6479   [(set (match_operand:SF 0 "register_operand" "")
6480         (plus:SF (match_operand:SF 1 "register_operand" "")
6481                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6482   "TARGET_80387 || TARGET_SSE_MATH"
6483   "")
6485 ;; Subtract instructions
6487 ;; %%% splits for subditi3
6489 (define_expand "subti3"
6490   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6491                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6492                              (match_operand:TI 2 "x86_64_general_operand" "")))
6493               (clobber (reg:CC FLAGS_REG))])]
6494   "TARGET_64BIT"
6495   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6497 (define_insn "*subti3_1"
6498   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6499         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6500                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6501    (clobber (reg:CC FLAGS_REG))]
6502   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6503   "#")
6505 (define_split
6506   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6507         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6508                   (match_operand:TI 2 "x86_64_general_operand" "")))
6509    (clobber (reg:CC FLAGS_REG))]
6510   "TARGET_64BIT && reload_completed"
6511   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6512               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6513    (parallel [(set (match_dup 3)
6514                    (minus:DI (match_dup 4)
6515                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6516                                       (match_dup 5))))
6517               (clobber (reg:CC FLAGS_REG))])]
6518   "split_ti (operands+0, 1, operands+0, operands+3);
6519    split_ti (operands+1, 1, operands+1, operands+4);
6520    split_ti (operands+2, 1, operands+2, operands+5);")
6522 ;; %%% splits for subsidi3
6524 (define_expand "subdi3"
6525   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6526                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6527                              (match_operand:DI 2 "x86_64_general_operand" "")))
6528               (clobber (reg:CC FLAGS_REG))])]
6529   ""
6530   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6532 (define_insn "*subdi3_1"
6533   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6534         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6535                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6536    (clobber (reg:CC FLAGS_REG))]
6537   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6538   "#")
6540 (define_split
6541   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6542         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6543                   (match_operand:DI 2 "general_operand" "")))
6544    (clobber (reg:CC FLAGS_REG))]
6545   "!TARGET_64BIT && reload_completed"
6546   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6547               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6548    (parallel [(set (match_dup 3)
6549                    (minus:SI (match_dup 4)
6550                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6551                                       (match_dup 5))))
6552               (clobber (reg:CC FLAGS_REG))])]
6553   "split_di (operands+0, 1, operands+0, operands+3);
6554    split_di (operands+1, 1, operands+1, operands+4);
6555    split_di (operands+2, 1, operands+2, operands+5);")
6557 (define_insn "subdi3_carry_rex64"
6558   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6559           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6560             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6561                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6562    (clobber (reg:CC FLAGS_REG))]
6563   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6564   "sbb{q}\t{%2, %0|%0, %2}"
6565   [(set_attr "type" "alu")
6566    (set_attr "pent_pair" "pu")
6567    (set_attr "mode" "DI")])
6569 (define_insn "*subdi_1_rex64"
6570   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6571         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6572                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6573    (clobber (reg:CC FLAGS_REG))]
6574   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6575   "sub{q}\t{%2, %0|%0, %2}"
6576   [(set_attr "type" "alu")
6577    (set_attr "mode" "DI")])
6579 (define_insn "*subdi_2_rex64"
6580   [(set (reg FLAGS_REG)
6581         (compare
6582           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6583                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6584           (const_int 0)))
6585    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6586         (minus:DI (match_dup 1) (match_dup 2)))]
6587   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6588    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6589   "sub{q}\t{%2, %0|%0, %2}"
6590   [(set_attr "type" "alu")
6591    (set_attr "mode" "DI")])
6593 (define_insn "*subdi_3_rex63"
6594   [(set (reg FLAGS_REG)
6595         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6596                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6597    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6598         (minus:DI (match_dup 1) (match_dup 2)))]
6599   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6600    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6601   "sub{q}\t{%2, %0|%0, %2}"
6602   [(set_attr "type" "alu")
6603    (set_attr "mode" "DI")])
6605 (define_insn "subqi3_carry"
6606   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6607           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6608             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6609                (match_operand:QI 2 "general_operand" "qi,qm"))))
6610    (clobber (reg:CC FLAGS_REG))]
6611   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6612   "sbb{b}\t{%2, %0|%0, %2}"
6613   [(set_attr "type" "alu")
6614    (set_attr "pent_pair" "pu")
6615    (set_attr "mode" "QI")])
6617 (define_insn "subhi3_carry"
6618   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6619           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6620             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6621                (match_operand:HI 2 "general_operand" "ri,rm"))))
6622    (clobber (reg:CC FLAGS_REG))]
6623   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6624   "sbb{w}\t{%2, %0|%0, %2}"
6625   [(set_attr "type" "alu")
6626    (set_attr "pent_pair" "pu")
6627    (set_attr "mode" "HI")])
6629 (define_insn "subsi3_carry"
6630   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6631           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6632             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6633                (match_operand:SI 2 "general_operand" "ri,rm"))))
6634    (clobber (reg:CC FLAGS_REG))]
6635   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6636   "sbb{l}\t{%2, %0|%0, %2}"
6637   [(set_attr "type" "alu")
6638    (set_attr "pent_pair" "pu")
6639    (set_attr "mode" "SI")])
6641 (define_insn "subsi3_carry_zext"
6642   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6643           (zero_extend:DI
6644             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6645               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6646                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6647    (clobber (reg:CC FLAGS_REG))]
6648   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6649   "sbb{l}\t{%2, %k0|%k0, %2}"
6650   [(set_attr "type" "alu")
6651    (set_attr "pent_pair" "pu")
6652    (set_attr "mode" "SI")])
6654 (define_expand "subsi3"
6655   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6656                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6657                              (match_operand:SI 2 "general_operand" "")))
6658               (clobber (reg:CC FLAGS_REG))])]
6659   ""
6660   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6662 (define_insn "*subsi_1"
6663   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6664         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6665                   (match_operand:SI 2 "general_operand" "ri,rm")))
6666    (clobber (reg:CC FLAGS_REG))]
6667   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6668   "sub{l}\t{%2, %0|%0, %2}"
6669   [(set_attr "type" "alu")
6670    (set_attr "mode" "SI")])
6672 (define_insn "*subsi_1_zext"
6673   [(set (match_operand:DI 0 "register_operand" "=r")
6674         (zero_extend:DI
6675           (minus:SI (match_operand:SI 1 "register_operand" "0")
6676                     (match_operand:SI 2 "general_operand" "rim"))))
6677    (clobber (reg:CC FLAGS_REG))]
6678   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6679   "sub{l}\t{%2, %k0|%k0, %2}"
6680   [(set_attr "type" "alu")
6681    (set_attr "mode" "SI")])
6683 (define_insn "*subsi_2"
6684   [(set (reg FLAGS_REG)
6685         (compare
6686           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6687                     (match_operand:SI 2 "general_operand" "ri,rm"))
6688           (const_int 0)))
6689    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6690         (minus:SI (match_dup 1) (match_dup 2)))]
6691   "ix86_match_ccmode (insn, CCGOCmode)
6692    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6693   "sub{l}\t{%2, %0|%0, %2}"
6694   [(set_attr "type" "alu")
6695    (set_attr "mode" "SI")])
6697 (define_insn "*subsi_2_zext"
6698   [(set (reg FLAGS_REG)
6699         (compare
6700           (minus:SI (match_operand:SI 1 "register_operand" "0")
6701                     (match_operand:SI 2 "general_operand" "rim"))
6702           (const_int 0)))
6703    (set (match_operand:DI 0 "register_operand" "=r")
6704         (zero_extend:DI
6705           (minus:SI (match_dup 1)
6706                     (match_dup 2))))]
6707   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6708    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6709   "sub{l}\t{%2, %k0|%k0, %2}"
6710   [(set_attr "type" "alu")
6711    (set_attr "mode" "SI")])
6713 (define_insn "*subsi_3"
6714   [(set (reg FLAGS_REG)
6715         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6716                  (match_operand:SI 2 "general_operand" "ri,rm")))
6717    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6718         (minus:SI (match_dup 1) (match_dup 2)))]
6719   "ix86_match_ccmode (insn, CCmode)
6720    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721   "sub{l}\t{%2, %0|%0, %2}"
6722   [(set_attr "type" "alu")
6723    (set_attr "mode" "SI")])
6725 (define_insn "*subsi_3_zext"
6726   [(set (reg FLAGS_REG)
6727         (compare (match_operand:SI 1 "register_operand" "0")
6728                  (match_operand:SI 2 "general_operand" "rim")))
6729    (set (match_operand:DI 0 "register_operand" "=r")
6730         (zero_extend:DI
6731           (minus:SI (match_dup 1)
6732                     (match_dup 2))))]
6733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6734    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735   "sub{l}\t{%2, %1|%1, %2}"
6736   [(set_attr "type" "alu")
6737    (set_attr "mode" "DI")])
6739 (define_expand "subhi3"
6740   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6741                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6742                              (match_operand:HI 2 "general_operand" "")))
6743               (clobber (reg:CC FLAGS_REG))])]
6744   "TARGET_HIMODE_MATH"
6745   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6747 (define_insn "*subhi_1"
6748   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6749         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6750                   (match_operand:HI 2 "general_operand" "ri,rm")))
6751    (clobber (reg:CC FLAGS_REG))]
6752   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6753   "sub{w}\t{%2, %0|%0, %2}"
6754   [(set_attr "type" "alu")
6755    (set_attr "mode" "HI")])
6757 (define_insn "*subhi_2"
6758   [(set (reg FLAGS_REG)
6759         (compare
6760           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6761                     (match_operand:HI 2 "general_operand" "ri,rm"))
6762           (const_int 0)))
6763    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6764         (minus:HI (match_dup 1) (match_dup 2)))]
6765   "ix86_match_ccmode (insn, CCGOCmode)
6766    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6767   "sub{w}\t{%2, %0|%0, %2}"
6768   [(set_attr "type" "alu")
6769    (set_attr "mode" "HI")])
6771 (define_insn "*subhi_3"
6772   [(set (reg FLAGS_REG)
6773         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6774                  (match_operand:HI 2 "general_operand" "ri,rm")))
6775    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6776         (minus:HI (match_dup 1) (match_dup 2)))]
6777   "ix86_match_ccmode (insn, CCmode)
6778    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6779   "sub{w}\t{%2, %0|%0, %2}"
6780   [(set_attr "type" "alu")
6781    (set_attr "mode" "HI")])
6783 (define_expand "subqi3"
6784   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6785                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6786                              (match_operand:QI 2 "general_operand" "")))
6787               (clobber (reg:CC FLAGS_REG))])]
6788   "TARGET_QIMODE_MATH"
6789   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6791 (define_insn "*subqi_1"
6792   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6793         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6794                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6795    (clobber (reg:CC FLAGS_REG))]
6796   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6797   "sub{b}\t{%2, %0|%0, %2}"
6798   [(set_attr "type" "alu")
6799    (set_attr "mode" "QI")])
6801 (define_insn "*subqi_1_slp"
6802   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6803         (minus:QI (match_dup 0)
6804                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6805    (clobber (reg:CC FLAGS_REG))]
6806   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6807    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6808   "sub{b}\t{%1, %0|%0, %1}"
6809   [(set_attr "type" "alu1")
6810    (set_attr "mode" "QI")])
6812 (define_insn "*subqi_2"
6813   [(set (reg FLAGS_REG)
6814         (compare
6815           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6816                     (match_operand:QI 2 "general_operand" "qi,qm"))
6817           (const_int 0)))
6818    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6819         (minus:HI (match_dup 1) (match_dup 2)))]
6820   "ix86_match_ccmode (insn, CCGOCmode)
6821    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6822   "sub{b}\t{%2, %0|%0, %2}"
6823   [(set_attr "type" "alu")
6824    (set_attr "mode" "QI")])
6826 (define_insn "*subqi_3"
6827   [(set (reg FLAGS_REG)
6828         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6829                  (match_operand:QI 2 "general_operand" "qi,qm")))
6830    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6831         (minus:HI (match_dup 1) (match_dup 2)))]
6832   "ix86_match_ccmode (insn, CCmode)
6833    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6834   "sub{b}\t{%2, %0|%0, %2}"
6835   [(set_attr "type" "alu")
6836    (set_attr "mode" "QI")])
6838 ;; The patterns that match these are at the end of this file.
6840 (define_expand "subxf3"
6841   [(set (match_operand:XF 0 "register_operand" "")
6842         (minus:XF (match_operand:XF 1 "register_operand" "")
6843                   (match_operand:XF 2 "register_operand" "")))]
6844   "TARGET_80387"
6845   "")
6847 (define_expand "subdf3"
6848   [(set (match_operand:DF 0 "register_operand" "")
6849         (minus:DF (match_operand:DF 1 "register_operand" "")
6850                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6851   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6852   "")
6854 (define_expand "subsf3"
6855   [(set (match_operand:SF 0 "register_operand" "")
6856         (minus:SF (match_operand:SF 1 "register_operand" "")
6857                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6858   "TARGET_80387 || TARGET_SSE_MATH"
6859   "")
6861 ;; Multiply instructions
6863 (define_expand "muldi3"
6864   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6865                    (mult:DI (match_operand:DI 1 "register_operand" "")
6866                             (match_operand:DI 2 "x86_64_general_operand" "")))
6867               (clobber (reg:CC FLAGS_REG))])]
6868   "TARGET_64BIT"
6869   "")
6871 ;; On AMDFAM10 
6872 ;; IMUL reg64, reg64, imm8      Direct
6873 ;; IMUL reg64, mem64, imm8      VectorPath
6874 ;; IMUL reg64, reg64, imm32     Direct
6875 ;; IMUL reg64, mem64, imm32     VectorPath 
6876 ;; IMUL reg64, reg64            Direct
6877 ;; IMUL reg64, mem64            Direct
6879 (define_insn "*muldi3_1_rex64"
6880   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6881         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6882                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6883    (clobber (reg:CC FLAGS_REG))]
6884   "TARGET_64BIT
6885    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6886   "@
6887    imul{q}\t{%2, %1, %0|%0, %1, %2}
6888    imul{q}\t{%2, %1, %0|%0, %1, %2}
6889    imul{q}\t{%2, %0|%0, %2}"
6890   [(set_attr "type" "imul")
6891    (set_attr "prefix_0f" "0,0,1")
6892    (set (attr "athlon_decode")
6893         (cond [(eq_attr "cpu" "athlon")
6894                   (const_string "vector")
6895                (eq_attr "alternative" "1")
6896                   (const_string "vector")
6897                (and (eq_attr "alternative" "2")
6898                     (match_operand 1 "memory_operand" ""))
6899                   (const_string "vector")]
6900               (const_string "direct")))
6901    (set (attr "amdfam10_decode")
6902         (cond [(and (eq_attr "alternative" "0,1")
6903                     (match_operand 1 "memory_operand" ""))
6904                   (const_string "vector")]
6905               (const_string "direct")))       
6906    (set_attr "mode" "DI")])
6908 (define_expand "mulsi3"
6909   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6910                    (mult:SI (match_operand:SI 1 "register_operand" "")
6911                             (match_operand:SI 2 "general_operand" "")))
6912               (clobber (reg:CC FLAGS_REG))])]
6913   ""
6914   "")
6916 ;; On AMDFAM10 
6917 ;; IMUL reg32, reg32, imm8      Direct
6918 ;; IMUL reg32, mem32, imm8      VectorPath
6919 ;; IMUL reg32, reg32, imm32     Direct
6920 ;; IMUL reg32, mem32, imm32     VectorPath
6921 ;; IMUL reg32, reg32            Direct
6922 ;; IMUL reg32, mem32            Direct
6924 (define_insn "*mulsi3_1"
6925   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6926         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6927                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6928    (clobber (reg:CC FLAGS_REG))]
6929   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6930   "@
6931    imul{l}\t{%2, %1, %0|%0, %1, %2}
6932    imul{l}\t{%2, %1, %0|%0, %1, %2}
6933    imul{l}\t{%2, %0|%0, %2}"
6934   [(set_attr "type" "imul")
6935    (set_attr "prefix_0f" "0,0,1")
6936    (set (attr "athlon_decode")
6937         (cond [(eq_attr "cpu" "athlon")
6938                   (const_string "vector")
6939                (eq_attr "alternative" "1")
6940                   (const_string "vector")
6941                (and (eq_attr "alternative" "2")
6942                     (match_operand 1 "memory_operand" ""))
6943                   (const_string "vector")]
6944               (const_string "direct")))
6945    (set (attr "amdfam10_decode")
6946         (cond [(and (eq_attr "alternative" "0,1")
6947                     (match_operand 1 "memory_operand" ""))
6948                   (const_string "vector")]
6949               (const_string "direct")))       
6950    (set_attr "mode" "SI")])
6952 (define_insn "*mulsi3_1_zext"
6953   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6954         (zero_extend:DI
6955           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6956                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6957    (clobber (reg:CC FLAGS_REG))]
6958   "TARGET_64BIT
6959    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6960   "@
6961    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6962    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6963    imul{l}\t{%2, %k0|%k0, %2}"
6964   [(set_attr "type" "imul")
6965    (set_attr "prefix_0f" "0,0,1")
6966    (set (attr "athlon_decode")
6967         (cond [(eq_attr "cpu" "athlon")
6968                   (const_string "vector")
6969                (eq_attr "alternative" "1")
6970                   (const_string "vector")
6971                (and (eq_attr "alternative" "2")
6972                     (match_operand 1 "memory_operand" ""))
6973                   (const_string "vector")]
6974               (const_string "direct")))
6975    (set (attr "amdfam10_decode")
6976         (cond [(and (eq_attr "alternative" "0,1")
6977                     (match_operand 1 "memory_operand" ""))
6978                   (const_string "vector")]
6979               (const_string "direct")))       
6980    (set_attr "mode" "SI")])
6982 (define_expand "mulhi3"
6983   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6984                    (mult:HI (match_operand:HI 1 "register_operand" "")
6985                             (match_operand:HI 2 "general_operand" "")))
6986               (clobber (reg:CC FLAGS_REG))])]
6987   "TARGET_HIMODE_MATH"
6988   "")
6990 ;; On AMDFAM10
6991 ;; IMUL reg16, reg16, imm8      VectorPath
6992 ;; IMUL reg16, mem16, imm8      VectorPath
6993 ;; IMUL reg16, reg16, imm16     VectorPath
6994 ;; IMUL reg16, mem16, imm16     VectorPath
6995 ;; IMUL reg16, reg16            Direct
6996 ;; IMUL reg16, mem16            Direct
6997 (define_insn "*mulhi3_1"
6998   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6999         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7000                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7001    (clobber (reg:CC FLAGS_REG))]
7002   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7003   "@
7004    imul{w}\t{%2, %1, %0|%0, %1, %2}
7005    imul{w}\t{%2, %1, %0|%0, %1, %2}
7006    imul{w}\t{%2, %0|%0, %2}"
7007   [(set_attr "type" "imul")
7008    (set_attr "prefix_0f" "0,0,1")
7009    (set (attr "athlon_decode")
7010         (cond [(eq_attr "cpu" "athlon")
7011                   (const_string "vector")
7012                (eq_attr "alternative" "1,2")
7013                   (const_string "vector")]
7014               (const_string "direct")))
7015    (set (attr "amdfam10_decode")
7016         (cond [(eq_attr "alternative" "0,1")
7017                   (const_string "vector")]
7018               (const_string "direct")))
7019    (set_attr "mode" "HI")])
7021 (define_expand "mulqi3"
7022   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7023                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7024                             (match_operand:QI 2 "register_operand" "")))
7025               (clobber (reg:CC FLAGS_REG))])]
7026   "TARGET_QIMODE_MATH"
7027   "")
7029 ;;On AMDFAM10
7030 ;; MUL reg8     Direct
7031 ;; MUL mem8     Direct
7033 (define_insn "*mulqi3_1"
7034   [(set (match_operand:QI 0 "register_operand" "=a")
7035         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7036                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7037    (clobber (reg:CC FLAGS_REG))]
7038   "TARGET_QIMODE_MATH
7039    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7040   "mul{b}\t%2"
7041   [(set_attr "type" "imul")
7042    (set_attr "length_immediate" "0")
7043    (set (attr "athlon_decode")
7044      (if_then_else (eq_attr "cpu" "athlon")
7045         (const_string "vector")
7046         (const_string "direct")))
7047    (set_attr "amdfam10_decode" "direct")        
7048    (set_attr "mode" "QI")])
7050 (define_expand "umulqihi3"
7051   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7052                    (mult:HI (zero_extend:HI
7053                               (match_operand:QI 1 "nonimmediate_operand" ""))
7054                             (zero_extend:HI
7055                               (match_operand:QI 2 "register_operand" ""))))
7056               (clobber (reg:CC FLAGS_REG))])]
7057   "TARGET_QIMODE_MATH"
7058   "")
7060 (define_insn "*umulqihi3_1"
7061   [(set (match_operand:HI 0 "register_operand" "=a")
7062         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7063                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7064    (clobber (reg:CC FLAGS_REG))]
7065   "TARGET_QIMODE_MATH
7066    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7067   "mul{b}\t%2"
7068   [(set_attr "type" "imul")
7069    (set_attr "length_immediate" "0")
7070    (set (attr "athlon_decode")
7071      (if_then_else (eq_attr "cpu" "athlon")
7072         (const_string "vector")
7073         (const_string "direct")))
7074    (set_attr "amdfam10_decode" "direct")        
7075    (set_attr "mode" "QI")])
7077 (define_expand "mulqihi3"
7078   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7079                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7080                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7081               (clobber (reg:CC FLAGS_REG))])]
7082   "TARGET_QIMODE_MATH"
7083   "")
7085 (define_insn "*mulqihi3_insn"
7086   [(set (match_operand:HI 0 "register_operand" "=a")
7087         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7088                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7089    (clobber (reg:CC FLAGS_REG))]
7090   "TARGET_QIMODE_MATH
7091    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7092   "imul{b}\t%2"
7093   [(set_attr "type" "imul")
7094    (set_attr "length_immediate" "0")
7095    (set (attr "athlon_decode")
7096      (if_then_else (eq_attr "cpu" "athlon")
7097         (const_string "vector")
7098         (const_string "direct")))
7099    (set_attr "amdfam10_decode" "direct")        
7100    (set_attr "mode" "QI")])
7102 (define_expand "umulditi3"
7103   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7104                    (mult:TI (zero_extend:TI
7105                               (match_operand:DI 1 "nonimmediate_operand" ""))
7106                             (zero_extend:TI
7107                               (match_operand:DI 2 "register_operand" ""))))
7108               (clobber (reg:CC FLAGS_REG))])]
7109   "TARGET_64BIT"
7110   "")
7112 (define_insn "*umulditi3_insn"
7113   [(set (match_operand:TI 0 "register_operand" "=A")
7114         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7115                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7116    (clobber (reg:CC FLAGS_REG))]
7117   "TARGET_64BIT
7118    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7119   "mul{q}\t%2"
7120   [(set_attr "type" "imul")
7121    (set_attr "length_immediate" "0")
7122    (set (attr "athlon_decode")
7123      (if_then_else (eq_attr "cpu" "athlon")
7124         (const_string "vector")
7125         (const_string "double")))
7126    (set_attr "amdfam10_decode" "double")        
7127    (set_attr "mode" "DI")])
7129 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7130 (define_expand "umulsidi3"
7131   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7132                    (mult:DI (zero_extend:DI
7133                               (match_operand:SI 1 "nonimmediate_operand" ""))
7134                             (zero_extend:DI
7135                               (match_operand:SI 2 "register_operand" ""))))
7136               (clobber (reg:CC FLAGS_REG))])]
7137   "!TARGET_64BIT"
7138   "")
7140 (define_insn "*umulsidi3_insn"
7141   [(set (match_operand:DI 0 "register_operand" "=A")
7142         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7143                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7144    (clobber (reg:CC FLAGS_REG))]
7145   "!TARGET_64BIT
7146    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7147   "mul{l}\t%2"
7148   [(set_attr "type" "imul")
7149    (set_attr "length_immediate" "0")
7150    (set (attr "athlon_decode")
7151      (if_then_else (eq_attr "cpu" "athlon")
7152         (const_string "vector")
7153         (const_string "double")))
7154    (set_attr "amdfam10_decode" "double")        
7155    (set_attr "mode" "SI")])
7157 (define_expand "mulditi3"
7158   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7159                    (mult:TI (sign_extend:TI
7160                               (match_operand:DI 1 "nonimmediate_operand" ""))
7161                             (sign_extend:TI
7162                               (match_operand:DI 2 "register_operand" ""))))
7163               (clobber (reg:CC FLAGS_REG))])]
7164   "TARGET_64BIT"
7165   "")
7167 (define_insn "*mulditi3_insn"
7168   [(set (match_operand:TI 0 "register_operand" "=A")
7169         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7170                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7171    (clobber (reg:CC FLAGS_REG))]
7172   "TARGET_64BIT
7173    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7174   "imul{q}\t%2"
7175   [(set_attr "type" "imul")
7176    (set_attr "length_immediate" "0")
7177    (set (attr "athlon_decode")
7178      (if_then_else (eq_attr "cpu" "athlon")
7179         (const_string "vector")
7180         (const_string "double")))
7181    (set_attr "amdfam10_decode" "double")
7182    (set_attr "mode" "DI")])
7184 (define_expand "mulsidi3"
7185   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7186                    (mult:DI (sign_extend:DI
7187                               (match_operand:SI 1 "nonimmediate_operand" ""))
7188                             (sign_extend:DI
7189                               (match_operand:SI 2 "register_operand" ""))))
7190               (clobber (reg:CC FLAGS_REG))])]
7191   "!TARGET_64BIT"
7192   "")
7194 (define_insn "*mulsidi3_insn"
7195   [(set (match_operand:DI 0 "register_operand" "=A")
7196         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7197                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7198    (clobber (reg:CC FLAGS_REG))]
7199   "!TARGET_64BIT
7200    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7201   "imul{l}\t%2"
7202   [(set_attr "type" "imul")
7203    (set_attr "length_immediate" "0")
7204    (set (attr "athlon_decode")
7205      (if_then_else (eq_attr "cpu" "athlon")
7206         (const_string "vector")
7207         (const_string "double")))
7208    (set_attr "amdfam10_decode" "double")        
7209    (set_attr "mode" "SI")])
7211 (define_expand "umuldi3_highpart"
7212   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7213                    (truncate:DI
7214                      (lshiftrt:TI
7215                        (mult:TI (zero_extend:TI
7216                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7217                                 (zero_extend:TI
7218                                   (match_operand:DI 2 "register_operand" "")))
7219                        (const_int 64))))
7220               (clobber (match_scratch:DI 3 ""))
7221               (clobber (reg:CC FLAGS_REG))])]
7222   "TARGET_64BIT"
7223   "")
7225 (define_insn "*umuldi3_highpart_rex64"
7226   [(set (match_operand:DI 0 "register_operand" "=d")
7227         (truncate:DI
7228           (lshiftrt:TI
7229             (mult:TI (zero_extend:TI
7230                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7231                      (zero_extend:TI
7232                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7233             (const_int 64))))
7234    (clobber (match_scratch:DI 3 "=1"))
7235    (clobber (reg:CC FLAGS_REG))]
7236   "TARGET_64BIT
7237    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7238   "mul{q}\t%2"
7239   [(set_attr "type" "imul")
7240    (set_attr "length_immediate" "0")
7241    (set (attr "athlon_decode")
7242      (if_then_else (eq_attr "cpu" "athlon")
7243         (const_string "vector")
7244         (const_string "double")))
7245    (set_attr "amdfam10_decode" "double")        
7246    (set_attr "mode" "DI")])
7248 (define_expand "umulsi3_highpart"
7249   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7250                    (truncate:SI
7251                      (lshiftrt:DI
7252                        (mult:DI (zero_extend:DI
7253                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7254                                 (zero_extend:DI
7255                                   (match_operand:SI 2 "register_operand" "")))
7256                        (const_int 32))))
7257               (clobber (match_scratch:SI 3 ""))
7258               (clobber (reg:CC FLAGS_REG))])]
7259   ""
7260   "")
7262 (define_insn "*umulsi3_highpart_insn"
7263   [(set (match_operand:SI 0 "register_operand" "=d")
7264         (truncate:SI
7265           (lshiftrt:DI
7266             (mult:DI (zero_extend:DI
7267                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7268                      (zero_extend:DI
7269                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7270             (const_int 32))))
7271    (clobber (match_scratch:SI 3 "=1"))
7272    (clobber (reg:CC FLAGS_REG))]
7273   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7274   "mul{l}\t%2"
7275   [(set_attr "type" "imul")
7276    (set_attr "length_immediate" "0")
7277    (set (attr "athlon_decode")
7278      (if_then_else (eq_attr "cpu" "athlon")
7279         (const_string "vector")
7280         (const_string "double")))
7281    (set_attr "amdfam10_decode" "double")
7282    (set_attr "mode" "SI")])
7284 (define_insn "*umulsi3_highpart_zext"
7285   [(set (match_operand:DI 0 "register_operand" "=d")
7286         (zero_extend:DI (truncate:SI
7287           (lshiftrt:DI
7288             (mult:DI (zero_extend:DI
7289                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7290                      (zero_extend:DI
7291                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7292             (const_int 32)))))
7293    (clobber (match_scratch:SI 3 "=1"))
7294    (clobber (reg:CC FLAGS_REG))]
7295   "TARGET_64BIT
7296    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7297   "mul{l}\t%2"
7298   [(set_attr "type" "imul")
7299    (set_attr "length_immediate" "0")
7300    (set (attr "athlon_decode")
7301      (if_then_else (eq_attr "cpu" "athlon")
7302         (const_string "vector")
7303         (const_string "double")))
7304    (set_attr "amdfam10_decode" "double")
7305    (set_attr "mode" "SI")])
7307 (define_expand "smuldi3_highpart"
7308   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7309                    (truncate:DI
7310                      (lshiftrt:TI
7311                        (mult:TI (sign_extend:TI
7312                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7313                                 (sign_extend:TI
7314                                   (match_operand:DI 2 "register_operand" "")))
7315                        (const_int 64))))
7316               (clobber (match_scratch:DI 3 ""))
7317               (clobber (reg:CC FLAGS_REG))])]
7318   "TARGET_64BIT"
7319   "")
7321 (define_insn "*smuldi3_highpart_rex64"
7322   [(set (match_operand:DI 0 "register_operand" "=d")
7323         (truncate:DI
7324           (lshiftrt:TI
7325             (mult:TI (sign_extend:TI
7326                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7327                      (sign_extend:TI
7328                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7329             (const_int 64))))
7330    (clobber (match_scratch:DI 3 "=1"))
7331    (clobber (reg:CC FLAGS_REG))]
7332   "TARGET_64BIT
7333    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7334   "imul{q}\t%2"
7335   [(set_attr "type" "imul")
7336    (set (attr "athlon_decode")
7337      (if_then_else (eq_attr "cpu" "athlon")
7338         (const_string "vector")
7339         (const_string "double")))
7340    (set_attr "amdfam10_decode" "double")
7341    (set_attr "mode" "DI")])
7343 (define_expand "smulsi3_highpart"
7344   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7345                    (truncate:SI
7346                      (lshiftrt:DI
7347                        (mult:DI (sign_extend:DI
7348                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7349                                 (sign_extend:DI
7350                                   (match_operand:SI 2 "register_operand" "")))
7351                        (const_int 32))))
7352               (clobber (match_scratch:SI 3 ""))
7353               (clobber (reg:CC FLAGS_REG))])]
7354   ""
7355   "")
7357 (define_insn "*smulsi3_highpart_insn"
7358   [(set (match_operand:SI 0 "register_operand" "=d")
7359         (truncate:SI
7360           (lshiftrt:DI
7361             (mult:DI (sign_extend:DI
7362                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7363                      (sign_extend:DI
7364                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7365             (const_int 32))))
7366    (clobber (match_scratch:SI 3 "=1"))
7367    (clobber (reg:CC FLAGS_REG))]
7368   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7369   "imul{l}\t%2"
7370   [(set_attr "type" "imul")
7371    (set (attr "athlon_decode")
7372      (if_then_else (eq_attr "cpu" "athlon")
7373         (const_string "vector")
7374         (const_string "double")))
7375    (set_attr "amdfam10_decode" "double")
7376    (set_attr "mode" "SI")])
7378 (define_insn "*smulsi3_highpart_zext"
7379   [(set (match_operand:DI 0 "register_operand" "=d")
7380         (zero_extend:DI (truncate:SI
7381           (lshiftrt:DI
7382             (mult:DI (sign_extend:DI
7383                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7384                      (sign_extend:DI
7385                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7386             (const_int 32)))))
7387    (clobber (match_scratch:SI 3 "=1"))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "TARGET_64BIT
7390    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7391   "imul{l}\t%2"
7392   [(set_attr "type" "imul")
7393    (set (attr "athlon_decode")
7394      (if_then_else (eq_attr "cpu" "athlon")
7395         (const_string "vector")
7396         (const_string "double")))
7397    (set_attr "amdfam10_decode" "double")
7398    (set_attr "mode" "SI")])
7400 ;; The patterns that match these are at the end of this file.
7402 (define_expand "mulxf3"
7403   [(set (match_operand:XF 0 "register_operand" "")
7404         (mult:XF (match_operand:XF 1 "register_operand" "")
7405                  (match_operand:XF 2 "register_operand" "")))]
7406   "TARGET_80387"
7407   "")
7409 (define_expand "muldf3"
7410   [(set (match_operand:DF 0 "register_operand" "")
7411         (mult:DF (match_operand:DF 1 "register_operand" "")
7412                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7413   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7414   "")
7416 (define_expand "mulsf3"
7417   [(set (match_operand:SF 0 "register_operand" "")
7418         (mult:SF (match_operand:SF 1 "register_operand" "")
7419                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7420   "TARGET_80387 || TARGET_SSE_MATH"
7421   "")
7423 ;; Divide instructions
7425 (define_insn "divqi3"
7426   [(set (match_operand:QI 0 "register_operand" "=a")
7427         (div:QI (match_operand:HI 1 "register_operand" "0")
7428                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7429    (clobber (reg:CC FLAGS_REG))]
7430   "TARGET_QIMODE_MATH"
7431   "idiv{b}\t%2"
7432   [(set_attr "type" "idiv")
7433    (set_attr "mode" "QI")])
7435 (define_insn "udivqi3"
7436   [(set (match_operand:QI 0 "register_operand" "=a")
7437         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7438                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7439    (clobber (reg:CC FLAGS_REG))]
7440   "TARGET_QIMODE_MATH"
7441   "div{b}\t%2"
7442   [(set_attr "type" "idiv")
7443    (set_attr "mode" "QI")])
7445 ;; The patterns that match these are at the end of this file.
7447 (define_expand "divxf3"
7448   [(set (match_operand:XF 0 "register_operand" "")
7449         (div:XF (match_operand:XF 1 "register_operand" "")
7450                 (match_operand:XF 2 "register_operand" "")))]
7451   "TARGET_80387"
7452   "")
7454 (define_expand "divdf3"
7455   [(set (match_operand:DF 0 "register_operand" "")
7456         (div:DF (match_operand:DF 1 "register_operand" "")
7457                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7458    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7459    "")
7461 (define_expand "divsf3"
7462   [(set (match_operand:SF 0 "register_operand" "")
7463         (div:SF (match_operand:SF 1 "register_operand" "")
7464                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7465   "TARGET_80387 || TARGET_SSE_MATH"
7466   "")
7468 ;; Remainder instructions.
7470 (define_expand "divmoddi4"
7471   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7472                    (div:DI (match_operand:DI 1 "register_operand" "")
7473                            (match_operand:DI 2 "nonimmediate_operand" "")))
7474               (set (match_operand:DI 3 "register_operand" "")
7475                    (mod:DI (match_dup 1) (match_dup 2)))
7476               (clobber (reg:CC FLAGS_REG))])]
7477   "TARGET_64BIT"
7478   "")
7480 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7481 ;; Penalize eax case slightly because it results in worse scheduling
7482 ;; of code.
7483 (define_insn "*divmoddi4_nocltd_rex64"
7484   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7485         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7486                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7487    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7488         (mod:DI (match_dup 2) (match_dup 3)))
7489    (clobber (reg:CC FLAGS_REG))]
7490   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7491   "#"
7492   [(set_attr "type" "multi")])
7494 (define_insn "*divmoddi4_cltd_rex64"
7495   [(set (match_operand:DI 0 "register_operand" "=a")
7496         (div:DI (match_operand:DI 2 "register_operand" "a")
7497                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7498    (set (match_operand:DI 1 "register_operand" "=&d")
7499         (mod:DI (match_dup 2) (match_dup 3)))
7500    (clobber (reg:CC FLAGS_REG))]
7501   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7502   "#"
7503   [(set_attr "type" "multi")])
7505 (define_insn "*divmoddi_noext_rex64"
7506   [(set (match_operand:DI 0 "register_operand" "=a")
7507         (div:DI (match_operand:DI 1 "register_operand" "0")
7508                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7509    (set (match_operand:DI 3 "register_operand" "=d")
7510         (mod:DI (match_dup 1) (match_dup 2)))
7511    (use (match_operand:DI 4 "register_operand" "3"))
7512    (clobber (reg:CC FLAGS_REG))]
7513   "TARGET_64BIT"
7514   "idiv{q}\t%2"
7515   [(set_attr "type" "idiv")
7516    (set_attr "mode" "DI")])
7518 (define_split
7519   [(set (match_operand:DI 0 "register_operand" "")
7520         (div:DI (match_operand:DI 1 "register_operand" "")
7521                 (match_operand:DI 2 "nonimmediate_operand" "")))
7522    (set (match_operand:DI 3 "register_operand" "")
7523         (mod:DI (match_dup 1) (match_dup 2)))
7524    (clobber (reg:CC FLAGS_REG))]
7525   "TARGET_64BIT && reload_completed"
7526   [(parallel [(set (match_dup 3)
7527                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7528               (clobber (reg:CC FLAGS_REG))])
7529    (parallel [(set (match_dup 0)
7530                    (div:DI (reg:DI 0) (match_dup 2)))
7531               (set (match_dup 3)
7532                    (mod:DI (reg:DI 0) (match_dup 2)))
7533               (use (match_dup 3))
7534               (clobber (reg:CC FLAGS_REG))])]
7536   /* Avoid use of cltd in favor of a mov+shift.  */
7537   if (!TARGET_USE_CLTD && !optimize_size)
7538     {
7539       if (true_regnum (operands[1]))
7540         emit_move_insn (operands[0], operands[1]);
7541       else
7542         emit_move_insn (operands[3], operands[1]);
7543       operands[4] = operands[3];
7544     }
7545   else
7546     {
7547       gcc_assert (!true_regnum (operands[1]));
7548       operands[4] = operands[1];
7549     }
7553 (define_expand "divmodsi4"
7554   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7555                    (div:SI (match_operand:SI 1 "register_operand" "")
7556                            (match_operand:SI 2 "nonimmediate_operand" "")))
7557               (set (match_operand:SI 3 "register_operand" "")
7558                    (mod:SI (match_dup 1) (match_dup 2)))
7559               (clobber (reg:CC FLAGS_REG))])]
7560   ""
7561   "")
7563 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7564 ;; Penalize eax case slightly because it results in worse scheduling
7565 ;; of code.
7566 (define_insn "*divmodsi4_nocltd"
7567   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7568         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7569                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7570    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7571         (mod:SI (match_dup 2) (match_dup 3)))
7572    (clobber (reg:CC FLAGS_REG))]
7573   "!optimize_size && !TARGET_USE_CLTD"
7574   "#"
7575   [(set_attr "type" "multi")])
7577 (define_insn "*divmodsi4_cltd"
7578   [(set (match_operand:SI 0 "register_operand" "=a")
7579         (div:SI (match_operand:SI 2 "register_operand" "a")
7580                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7581    (set (match_operand:SI 1 "register_operand" "=&d")
7582         (mod:SI (match_dup 2) (match_dup 3)))
7583    (clobber (reg:CC FLAGS_REG))]
7584   "optimize_size || TARGET_USE_CLTD"
7585   "#"
7586   [(set_attr "type" "multi")])
7588 (define_insn "*divmodsi_noext"
7589   [(set (match_operand:SI 0 "register_operand" "=a")
7590         (div:SI (match_operand:SI 1 "register_operand" "0")
7591                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7592    (set (match_operand:SI 3 "register_operand" "=d")
7593         (mod:SI (match_dup 1) (match_dup 2)))
7594    (use (match_operand:SI 4 "register_operand" "3"))
7595    (clobber (reg:CC FLAGS_REG))]
7596   ""
7597   "idiv{l}\t%2"
7598   [(set_attr "type" "idiv")
7599    (set_attr "mode" "SI")])
7601 (define_split
7602   [(set (match_operand:SI 0 "register_operand" "")
7603         (div:SI (match_operand:SI 1 "register_operand" "")
7604                 (match_operand:SI 2 "nonimmediate_operand" "")))
7605    (set (match_operand:SI 3 "register_operand" "")
7606         (mod:SI (match_dup 1) (match_dup 2)))
7607    (clobber (reg:CC FLAGS_REG))]
7608   "reload_completed"
7609   [(parallel [(set (match_dup 3)
7610                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7611               (clobber (reg:CC FLAGS_REG))])
7612    (parallel [(set (match_dup 0)
7613                    (div:SI (reg:SI 0) (match_dup 2)))
7614               (set (match_dup 3)
7615                    (mod:SI (reg:SI 0) (match_dup 2)))
7616               (use (match_dup 3))
7617               (clobber (reg:CC FLAGS_REG))])]
7619   /* Avoid use of cltd in favor of a mov+shift.  */
7620   if (!TARGET_USE_CLTD && !optimize_size)
7621     {
7622       if (true_regnum (operands[1]))
7623         emit_move_insn (operands[0], operands[1]);
7624       else
7625         emit_move_insn (operands[3], operands[1]);
7626       operands[4] = operands[3];
7627     }
7628   else
7629     {
7630       gcc_assert (!true_regnum (operands[1]));
7631       operands[4] = operands[1];
7632     }
7634 ;; %%% Split me.
7635 (define_insn "divmodhi4"
7636   [(set (match_operand:HI 0 "register_operand" "=a")
7637         (div:HI (match_operand:HI 1 "register_operand" "0")
7638                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7639    (set (match_operand:HI 3 "register_operand" "=&d")
7640         (mod:HI (match_dup 1) (match_dup 2)))
7641    (clobber (reg:CC FLAGS_REG))]
7642   "TARGET_HIMODE_MATH"
7643   "cwtd\;idiv{w}\t%2"
7644   [(set_attr "type" "multi")
7645    (set_attr "length_immediate" "0")
7646    (set_attr "mode" "SI")])
7648 (define_insn "udivmoddi4"
7649   [(set (match_operand:DI 0 "register_operand" "=a")
7650         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7651                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7652    (set (match_operand:DI 3 "register_operand" "=&d")
7653         (umod:DI (match_dup 1) (match_dup 2)))
7654    (clobber (reg:CC FLAGS_REG))]
7655   "TARGET_64BIT"
7656   "xor{q}\t%3, %3\;div{q}\t%2"
7657   [(set_attr "type" "multi")
7658    (set_attr "length_immediate" "0")
7659    (set_attr "mode" "DI")])
7661 (define_insn "*udivmoddi4_noext"
7662   [(set (match_operand:DI 0 "register_operand" "=a")
7663         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7664                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7665    (set (match_operand:DI 3 "register_operand" "=d")
7666         (umod:DI (match_dup 1) (match_dup 2)))
7667    (use (match_dup 3))
7668    (clobber (reg:CC FLAGS_REG))]
7669   "TARGET_64BIT"
7670   "div{q}\t%2"
7671   [(set_attr "type" "idiv")
7672    (set_attr "mode" "DI")])
7674 (define_split
7675   [(set (match_operand:DI 0 "register_operand" "")
7676         (udiv:DI (match_operand:DI 1 "register_operand" "")
7677                  (match_operand:DI 2 "nonimmediate_operand" "")))
7678    (set (match_operand:DI 3 "register_operand" "")
7679         (umod:DI (match_dup 1) (match_dup 2)))
7680    (clobber (reg:CC FLAGS_REG))]
7681   "TARGET_64BIT && reload_completed"
7682   [(set (match_dup 3) (const_int 0))
7683    (parallel [(set (match_dup 0)
7684                    (udiv:DI (match_dup 1) (match_dup 2)))
7685               (set (match_dup 3)
7686                    (umod:DI (match_dup 1) (match_dup 2)))
7687               (use (match_dup 3))
7688               (clobber (reg:CC FLAGS_REG))])]
7689   "")
7691 (define_insn "udivmodsi4"
7692   [(set (match_operand:SI 0 "register_operand" "=a")
7693         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7694                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7695    (set (match_operand:SI 3 "register_operand" "=&d")
7696         (umod:SI (match_dup 1) (match_dup 2)))
7697    (clobber (reg:CC FLAGS_REG))]
7698   ""
7699   "xor{l}\t%3, %3\;div{l}\t%2"
7700   [(set_attr "type" "multi")
7701    (set_attr "length_immediate" "0")
7702    (set_attr "mode" "SI")])
7704 (define_insn "*udivmodsi4_noext"
7705   [(set (match_operand:SI 0 "register_operand" "=a")
7706         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7707                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7708    (set (match_operand:SI 3 "register_operand" "=d")
7709         (umod:SI (match_dup 1) (match_dup 2)))
7710    (use (match_dup 3))
7711    (clobber (reg:CC FLAGS_REG))]
7712   ""
7713   "div{l}\t%2"
7714   [(set_attr "type" "idiv")
7715    (set_attr "mode" "SI")])
7717 (define_split
7718   [(set (match_operand:SI 0 "register_operand" "")
7719         (udiv:SI (match_operand:SI 1 "register_operand" "")
7720                  (match_operand:SI 2 "nonimmediate_operand" "")))
7721    (set (match_operand:SI 3 "register_operand" "")
7722         (umod:SI (match_dup 1) (match_dup 2)))
7723    (clobber (reg:CC FLAGS_REG))]
7724   "reload_completed"
7725   [(set (match_dup 3) (const_int 0))
7726    (parallel [(set (match_dup 0)
7727                    (udiv:SI (match_dup 1) (match_dup 2)))
7728               (set (match_dup 3)
7729                    (umod:SI (match_dup 1) (match_dup 2)))
7730               (use (match_dup 3))
7731               (clobber (reg:CC FLAGS_REG))])]
7732   "")
7734 (define_expand "udivmodhi4"
7735   [(set (match_dup 4) (const_int 0))
7736    (parallel [(set (match_operand:HI 0 "register_operand" "")
7737                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7738                             (match_operand:HI 2 "nonimmediate_operand" "")))
7739               (set (match_operand:HI 3 "register_operand" "")
7740                    (umod:HI (match_dup 1) (match_dup 2)))
7741               (use (match_dup 4))
7742               (clobber (reg:CC FLAGS_REG))])]
7743   "TARGET_HIMODE_MATH"
7744   "operands[4] = gen_reg_rtx (HImode);")
7746 (define_insn "*udivmodhi_noext"
7747   [(set (match_operand:HI 0 "register_operand" "=a")
7748         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7749                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7750    (set (match_operand:HI 3 "register_operand" "=d")
7751         (umod:HI (match_dup 1) (match_dup 2)))
7752    (use (match_operand:HI 4 "register_operand" "3"))
7753    (clobber (reg:CC FLAGS_REG))]
7754   ""
7755   "div{w}\t%2"
7756   [(set_attr "type" "idiv")
7757    (set_attr "mode" "HI")])
7759 ;; We cannot use div/idiv for double division, because it causes
7760 ;; "division by zero" on the overflow and that's not what we expect
7761 ;; from truncate.  Because true (non truncating) double division is
7762 ;; never generated, we can't create this insn anyway.
7764 ;(define_insn ""
7765 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7766 ;       (truncate:SI
7767 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7768 ;                  (zero_extend:DI
7769 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7770 ;   (set (match_operand:SI 3 "register_operand" "=d")
7771 ;       (truncate:SI
7772 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7773 ;   (clobber (reg:CC FLAGS_REG))]
7774 ;  ""
7775 ;  "div{l}\t{%2, %0|%0, %2}"
7776 ;  [(set_attr "type" "idiv")])
7778 ;;- Logical AND instructions
7780 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7781 ;; Note that this excludes ah.
7783 (define_insn "*testdi_1_rex64"
7784   [(set (reg FLAGS_REG)
7785         (compare
7786           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7787                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7788           (const_int 0)))]
7789   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7790    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7791   "@
7792    test{l}\t{%k1, %k0|%k0, %k1}
7793    test{l}\t{%k1, %k0|%k0, %k1}
7794    test{q}\t{%1, %0|%0, %1}
7795    test{q}\t{%1, %0|%0, %1}
7796    test{q}\t{%1, %0|%0, %1}"
7797   [(set_attr "type" "test")
7798    (set_attr "modrm" "0,1,0,1,1")
7799    (set_attr "mode" "SI,SI,DI,DI,DI")
7800    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7802 (define_insn "testsi_1"
7803   [(set (reg FLAGS_REG)
7804         (compare
7805           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7806                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7807           (const_int 0)))]
7808   "ix86_match_ccmode (insn, CCNOmode)
7809    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7810   "test{l}\t{%1, %0|%0, %1}"
7811   [(set_attr "type" "test")
7812    (set_attr "modrm" "0,1,1")
7813    (set_attr "mode" "SI")
7814    (set_attr "pent_pair" "uv,np,uv")])
7816 (define_expand "testsi_ccno_1"
7817   [(set (reg:CCNO FLAGS_REG)
7818         (compare:CCNO
7819           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7820                   (match_operand:SI 1 "nonmemory_operand" ""))
7821           (const_int 0)))]
7822   ""
7823   "")
7825 (define_insn "*testhi_1"
7826   [(set (reg FLAGS_REG)
7827         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7828                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7829                  (const_int 0)))]
7830   "ix86_match_ccmode (insn, CCNOmode)
7831    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7832   "test{w}\t{%1, %0|%0, %1}"
7833   [(set_attr "type" "test")
7834    (set_attr "modrm" "0,1,1")
7835    (set_attr "mode" "HI")
7836    (set_attr "pent_pair" "uv,np,uv")])
7838 (define_expand "testqi_ccz_1"
7839   [(set (reg:CCZ FLAGS_REG)
7840         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7841                              (match_operand:QI 1 "nonmemory_operand" ""))
7842                  (const_int 0)))]
7843   ""
7844   "")
7846 (define_insn "*testqi_1_maybe_si"
7847   [(set (reg FLAGS_REG)
7848         (compare
7849           (and:QI
7850             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7851             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7852           (const_int 0)))]
7853    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7854     && ix86_match_ccmode (insn,
7855                          CONST_INT_P (operands[1])
7856                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7858   if (which_alternative == 3)
7859     {
7860       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7861         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7862       return "test{l}\t{%1, %k0|%k0, %1}";
7863     }
7864   return "test{b}\t{%1, %0|%0, %1}";
7866   [(set_attr "type" "test")
7867    (set_attr "modrm" "0,1,1,1")
7868    (set_attr "mode" "QI,QI,QI,SI")
7869    (set_attr "pent_pair" "uv,np,uv,np")])
7871 (define_insn "*testqi_1"
7872   [(set (reg FLAGS_REG)
7873         (compare
7874           (and:QI
7875             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7876             (match_operand:QI 1 "general_operand" "n,n,qn"))
7877           (const_int 0)))]
7878   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7879    && ix86_match_ccmode (insn, CCNOmode)"
7880   "test{b}\t{%1, %0|%0, %1}"
7881   [(set_attr "type" "test")
7882    (set_attr "modrm" "0,1,1")
7883    (set_attr "mode" "QI")
7884    (set_attr "pent_pair" "uv,np,uv")])
7886 (define_expand "testqi_ext_ccno_0"
7887   [(set (reg:CCNO FLAGS_REG)
7888         (compare:CCNO
7889           (and:SI
7890             (zero_extract:SI
7891               (match_operand 0 "ext_register_operand" "")
7892               (const_int 8)
7893               (const_int 8))
7894             (match_operand 1 "const_int_operand" ""))
7895           (const_int 0)))]
7896   ""
7897   "")
7899 (define_insn "*testqi_ext_0"
7900   [(set (reg FLAGS_REG)
7901         (compare
7902           (and:SI
7903             (zero_extract:SI
7904               (match_operand 0 "ext_register_operand" "Q")
7905               (const_int 8)
7906               (const_int 8))
7907             (match_operand 1 "const_int_operand" "n"))
7908           (const_int 0)))]
7909   "ix86_match_ccmode (insn, CCNOmode)"
7910   "test{b}\t{%1, %h0|%h0, %1}"
7911   [(set_attr "type" "test")
7912    (set_attr "mode" "QI")
7913    (set_attr "length_immediate" "1")
7914    (set_attr "pent_pair" "np")])
7916 (define_insn "*testqi_ext_1"
7917   [(set (reg FLAGS_REG)
7918         (compare
7919           (and:SI
7920             (zero_extract:SI
7921               (match_operand 0 "ext_register_operand" "Q")
7922               (const_int 8)
7923               (const_int 8))
7924             (zero_extend:SI
7925               (match_operand:QI 1 "general_operand" "Qm")))
7926           (const_int 0)))]
7927   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7928    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7929   "test{b}\t{%1, %h0|%h0, %1}"
7930   [(set_attr "type" "test")
7931    (set_attr "mode" "QI")])
7933 (define_insn "*testqi_ext_1_rex64"
7934   [(set (reg FLAGS_REG)
7935         (compare
7936           (and:SI
7937             (zero_extract:SI
7938               (match_operand 0 "ext_register_operand" "Q")
7939               (const_int 8)
7940               (const_int 8))
7941             (zero_extend:SI
7942               (match_operand:QI 1 "register_operand" "Q")))
7943           (const_int 0)))]
7944   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7945   "test{b}\t{%1, %h0|%h0, %1}"
7946   [(set_attr "type" "test")
7947    (set_attr "mode" "QI")])
7949 (define_insn "*testqi_ext_2"
7950   [(set (reg FLAGS_REG)
7951         (compare
7952           (and:SI
7953             (zero_extract:SI
7954               (match_operand 0 "ext_register_operand" "Q")
7955               (const_int 8)
7956               (const_int 8))
7957             (zero_extract:SI
7958               (match_operand 1 "ext_register_operand" "Q")
7959               (const_int 8)
7960               (const_int 8)))
7961           (const_int 0)))]
7962   "ix86_match_ccmode (insn, CCNOmode)"
7963   "test{b}\t{%h1, %h0|%h0, %h1}"
7964   [(set_attr "type" "test")
7965    (set_attr "mode" "QI")])
7967 ;; Combine likes to form bit extractions for some tests.  Humor it.
7968 (define_insn "*testqi_ext_3"
7969   [(set (reg FLAGS_REG)
7970         (compare (zero_extract:SI
7971                    (match_operand 0 "nonimmediate_operand" "rm")
7972                    (match_operand:SI 1 "const_int_operand" "")
7973                    (match_operand:SI 2 "const_int_operand" ""))
7974                  (const_int 0)))]
7975   "ix86_match_ccmode (insn, CCNOmode)
7976    && INTVAL (operands[1]) > 0
7977    && INTVAL (operands[2]) >= 0
7978    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7979    && (GET_MODE (operands[0]) == SImode
7980        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7981        || GET_MODE (operands[0]) == HImode
7982        || GET_MODE (operands[0]) == QImode)"
7983   "#")
7985 (define_insn "*testqi_ext_3_rex64"
7986   [(set (reg FLAGS_REG)
7987         (compare (zero_extract:DI
7988                    (match_operand 0 "nonimmediate_operand" "rm")
7989                    (match_operand:DI 1 "const_int_operand" "")
7990                    (match_operand:DI 2 "const_int_operand" ""))
7991                  (const_int 0)))]
7992   "TARGET_64BIT
7993    && ix86_match_ccmode (insn, CCNOmode)
7994    && INTVAL (operands[1]) > 0
7995    && INTVAL (operands[2]) >= 0
7996    /* Ensure that resulting mask is zero or sign extended operand.  */
7997    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7998        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7999            && INTVAL (operands[1]) > 32))
8000    && (GET_MODE (operands[0]) == SImode
8001        || GET_MODE (operands[0]) == DImode
8002        || GET_MODE (operands[0]) == HImode
8003        || GET_MODE (operands[0]) == QImode)"
8004   "#")
8006 (define_split
8007   [(set (match_operand 0 "flags_reg_operand" "")
8008         (match_operator 1 "compare_operator"
8009           [(zero_extract
8010              (match_operand 2 "nonimmediate_operand" "")
8011              (match_operand 3 "const_int_operand" "")
8012              (match_operand 4 "const_int_operand" ""))
8013            (const_int 0)]))]
8014   "ix86_match_ccmode (insn, CCNOmode)"
8015   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8017   rtx val = operands[2];
8018   HOST_WIDE_INT len = INTVAL (operands[3]);
8019   HOST_WIDE_INT pos = INTVAL (operands[4]);
8020   HOST_WIDE_INT mask;
8021   enum machine_mode mode, submode;
8023   mode = GET_MODE (val);
8024   if (MEM_P (val))
8025     {
8026       /* ??? Combine likes to put non-volatile mem extractions in QImode
8027          no matter the size of the test.  So find a mode that works.  */
8028       if (! MEM_VOLATILE_P (val))
8029         {
8030           mode = smallest_mode_for_size (pos + len, MODE_INT);
8031           val = adjust_address (val, mode, 0);
8032         }
8033     }
8034   else if (GET_CODE (val) == SUBREG
8035            && (submode = GET_MODE (SUBREG_REG (val)),
8036                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8037            && pos + len <= GET_MODE_BITSIZE (submode))
8038     {
8039       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8040       mode = submode;
8041       val = SUBREG_REG (val);
8042     }
8043   else if (mode == HImode && pos + len <= 8)
8044     {
8045       /* Small HImode tests can be converted to QImode.  */
8046       mode = QImode;
8047       val = gen_lowpart (QImode, val);
8048     }
8050   if (len == HOST_BITS_PER_WIDE_INT)
8051     mask = -1;
8052   else
8053     mask = ((HOST_WIDE_INT)1 << len) - 1;
8054   mask <<= pos;
8056   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8059 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8060 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8061 ;; this is relatively important trick.
8062 ;; Do the conversion only post-reload to avoid limiting of the register class
8063 ;; to QI regs.
8064 (define_split
8065   [(set (match_operand 0 "flags_reg_operand" "")
8066         (match_operator 1 "compare_operator"
8067           [(and (match_operand 2 "register_operand" "")
8068                 (match_operand 3 "const_int_operand" ""))
8069            (const_int 0)]))]
8070    "reload_completed
8071     && QI_REG_P (operands[2])
8072     && GET_MODE (operands[2]) != QImode
8073     && ((ix86_match_ccmode (insn, CCZmode)
8074          && !(INTVAL (operands[3]) & ~(255 << 8)))
8075         || (ix86_match_ccmode (insn, CCNOmode)
8076             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8077   [(set (match_dup 0)
8078         (match_op_dup 1
8079           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8080                    (match_dup 3))
8081            (const_int 0)]))]
8082   "operands[2] = gen_lowpart (SImode, operands[2]);
8083    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8085 (define_split
8086   [(set (match_operand 0 "flags_reg_operand" "")
8087         (match_operator 1 "compare_operator"
8088           [(and (match_operand 2 "nonimmediate_operand" "")
8089                 (match_operand 3 "const_int_operand" ""))
8090            (const_int 0)]))]
8091    "reload_completed
8092     && GET_MODE (operands[2]) != QImode
8093     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8094     && ((ix86_match_ccmode (insn, CCZmode)
8095          && !(INTVAL (operands[3]) & ~255))
8096         || (ix86_match_ccmode (insn, CCNOmode)
8097             && !(INTVAL (operands[3]) & ~127)))"
8098   [(set (match_dup 0)
8099         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8100                          (const_int 0)]))]
8101   "operands[2] = gen_lowpart (QImode, operands[2]);
8102    operands[3] = gen_lowpart (QImode, operands[3]);")
8105 ;; %%% This used to optimize known byte-wide and operations to memory,
8106 ;; and sometimes to QImode registers.  If this is considered useful,
8107 ;; it should be done with splitters.
8109 (define_expand "anddi3"
8110   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8111         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8112                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8113    (clobber (reg:CC FLAGS_REG))]
8114   "TARGET_64BIT"
8115   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8117 (define_insn "*anddi_1_rex64"
8118   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8119         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8120                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8121    (clobber (reg:CC FLAGS_REG))]
8122   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8124   switch (get_attr_type (insn))
8125     {
8126     case TYPE_IMOVX:
8127       {
8128         enum machine_mode mode;
8130         gcc_assert (CONST_INT_P (operands[2]));
8131         if (INTVAL (operands[2]) == 0xff)
8132           mode = QImode;
8133         else
8134           {
8135             gcc_assert (INTVAL (operands[2]) == 0xffff);
8136             mode = HImode;
8137           }
8139         operands[1] = gen_lowpart (mode, operands[1]);
8140         if (mode == QImode)
8141           return "movz{bq|x}\t{%1,%0|%0, %1}";
8142         else
8143           return "movz{wq|x}\t{%1,%0|%0, %1}";
8144       }
8146     default:
8147       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8148       if (get_attr_mode (insn) == MODE_SI)
8149         return "and{l}\t{%k2, %k0|%k0, %k2}";
8150       else
8151         return "and{q}\t{%2, %0|%0, %2}";
8152     }
8154   [(set_attr "type" "alu,alu,alu,imovx")
8155    (set_attr "length_immediate" "*,*,*,0")
8156    (set_attr "mode" "SI,DI,DI,DI")])
8158 (define_insn "*anddi_2"
8159   [(set (reg FLAGS_REG)
8160         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8161                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8162                  (const_int 0)))
8163    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8164         (and:DI (match_dup 1) (match_dup 2)))]
8165   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8166    && ix86_binary_operator_ok (AND, DImode, operands)"
8167   "@
8168    and{l}\t{%k2, %k0|%k0, %k2}
8169    and{q}\t{%2, %0|%0, %2}
8170    and{q}\t{%2, %0|%0, %2}"
8171   [(set_attr "type" "alu")
8172    (set_attr "mode" "SI,DI,DI")])
8174 (define_expand "andsi3"
8175   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8176         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8177                 (match_operand:SI 2 "general_operand" "")))
8178    (clobber (reg:CC FLAGS_REG))]
8179   ""
8180   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8182 (define_insn "*andsi_1"
8183   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8184         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8185                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8186    (clobber (reg:CC FLAGS_REG))]
8187   "ix86_binary_operator_ok (AND, SImode, operands)"
8189   switch (get_attr_type (insn))
8190     {
8191     case TYPE_IMOVX:
8192       {
8193         enum machine_mode mode;
8195         gcc_assert (CONST_INT_P (operands[2]));
8196         if (INTVAL (operands[2]) == 0xff)
8197           mode = QImode;
8198         else
8199           {
8200             gcc_assert (INTVAL (operands[2]) == 0xffff);
8201             mode = HImode;
8202           }
8204         operands[1] = gen_lowpart (mode, operands[1]);
8205         if (mode == QImode)
8206           return "movz{bl|x}\t{%1,%0|%0, %1}";
8207         else
8208           return "movz{wl|x}\t{%1,%0|%0, %1}";
8209       }
8211     default:
8212       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8213       return "and{l}\t{%2, %0|%0, %2}";
8214     }
8216   [(set_attr "type" "alu,alu,imovx")
8217    (set_attr "length_immediate" "*,*,0")
8218    (set_attr "mode" "SI")])
8220 (define_split
8221   [(set (match_operand 0 "register_operand" "")
8222         (and (match_dup 0)
8223              (const_int -65536)))
8224    (clobber (reg:CC FLAGS_REG))]
8225   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8226   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8227   "operands[1] = gen_lowpart (HImode, operands[0]);")
8229 (define_split
8230   [(set (match_operand 0 "ext_register_operand" "")
8231         (and (match_dup 0)
8232              (const_int -256)))
8233    (clobber (reg:CC FLAGS_REG))]
8234   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8235   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8236   "operands[1] = gen_lowpart (QImode, operands[0]);")
8238 (define_split
8239   [(set (match_operand 0 "ext_register_operand" "")
8240         (and (match_dup 0)
8241              (const_int -65281)))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8244   [(parallel [(set (zero_extract:SI (match_dup 0)
8245                                     (const_int 8)
8246                                     (const_int 8))
8247                    (xor:SI
8248                      (zero_extract:SI (match_dup 0)
8249                                       (const_int 8)
8250                                       (const_int 8))
8251                      (zero_extract:SI (match_dup 0)
8252                                       (const_int 8)
8253                                       (const_int 8))))
8254               (clobber (reg:CC FLAGS_REG))])]
8255   "operands[0] = gen_lowpart (SImode, operands[0]);")
8257 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8258 (define_insn "*andsi_1_zext"
8259   [(set (match_operand:DI 0 "register_operand" "=r")
8260         (zero_extend:DI
8261           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8262                   (match_operand:SI 2 "general_operand" "rim"))))
8263    (clobber (reg:CC FLAGS_REG))]
8264   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8265   "and{l}\t{%2, %k0|%k0, %2}"
8266   [(set_attr "type" "alu")
8267    (set_attr "mode" "SI")])
8269 (define_insn "*andsi_2"
8270   [(set (reg FLAGS_REG)
8271         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8272                          (match_operand:SI 2 "general_operand" "rim,ri"))
8273                  (const_int 0)))
8274    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8275         (and:SI (match_dup 1) (match_dup 2)))]
8276   "ix86_match_ccmode (insn, CCNOmode)
8277    && ix86_binary_operator_ok (AND, SImode, operands)"
8278   "and{l}\t{%2, %0|%0, %2}"
8279   [(set_attr "type" "alu")
8280    (set_attr "mode" "SI")])
8282 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8283 (define_insn "*andsi_2_zext"
8284   [(set (reg FLAGS_REG)
8285         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8286                          (match_operand:SI 2 "general_operand" "rim"))
8287                  (const_int 0)))
8288    (set (match_operand:DI 0 "register_operand" "=r")
8289         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8290   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8291    && ix86_binary_operator_ok (AND, SImode, operands)"
8292   "and{l}\t{%2, %k0|%k0, %2}"
8293   [(set_attr "type" "alu")
8294    (set_attr "mode" "SI")])
8296 (define_expand "andhi3"
8297   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8298         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8299                 (match_operand:HI 2 "general_operand" "")))
8300    (clobber (reg:CC FLAGS_REG))]
8301   "TARGET_HIMODE_MATH"
8302   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8304 (define_insn "*andhi_1"
8305   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8306         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8307                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8308    (clobber (reg:CC FLAGS_REG))]
8309   "ix86_binary_operator_ok (AND, HImode, operands)"
8311   switch (get_attr_type (insn))
8312     {
8313     case TYPE_IMOVX:
8314       gcc_assert (CONST_INT_P (operands[2]));
8315       gcc_assert (INTVAL (operands[2]) == 0xff);
8316       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8318     default:
8319       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8321       return "and{w}\t{%2, %0|%0, %2}";
8322     }
8324   [(set_attr "type" "alu,alu,imovx")
8325    (set_attr "length_immediate" "*,*,0")
8326    (set_attr "mode" "HI,HI,SI")])
8328 (define_insn "*andhi_2"
8329   [(set (reg FLAGS_REG)
8330         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8331                          (match_operand:HI 2 "general_operand" "rim,ri"))
8332                  (const_int 0)))
8333    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8334         (and:HI (match_dup 1) (match_dup 2)))]
8335   "ix86_match_ccmode (insn, CCNOmode)
8336    && ix86_binary_operator_ok (AND, HImode, operands)"
8337   "and{w}\t{%2, %0|%0, %2}"
8338   [(set_attr "type" "alu")
8339    (set_attr "mode" "HI")])
8341 (define_expand "andqi3"
8342   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8343         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8344                 (match_operand:QI 2 "general_operand" "")))
8345    (clobber (reg:CC FLAGS_REG))]
8346   "TARGET_QIMODE_MATH"
8347   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8349 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8350 (define_insn "*andqi_1"
8351   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8352         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8353                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8354    (clobber (reg:CC FLAGS_REG))]
8355   "ix86_binary_operator_ok (AND, QImode, operands)"
8356   "@
8357    and{b}\t{%2, %0|%0, %2}
8358    and{b}\t{%2, %0|%0, %2}
8359    and{l}\t{%k2, %k0|%k0, %k2}"
8360   [(set_attr "type" "alu")
8361    (set_attr "mode" "QI,QI,SI")])
8363 (define_insn "*andqi_1_slp"
8364   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8365         (and:QI (match_dup 0)
8366                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8367    (clobber (reg:CC FLAGS_REG))]
8368   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8369    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8370   "and{b}\t{%1, %0|%0, %1}"
8371   [(set_attr "type" "alu1")
8372    (set_attr "mode" "QI")])
8374 (define_insn "*andqi_2_maybe_si"
8375   [(set (reg FLAGS_REG)
8376         (compare (and:QI
8377                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8378                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8379                  (const_int 0)))
8380    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8381         (and:QI (match_dup 1) (match_dup 2)))]
8382   "ix86_binary_operator_ok (AND, QImode, operands)
8383    && ix86_match_ccmode (insn,
8384                          CONST_INT_P (operands[2])
8385                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8387   if (which_alternative == 2)
8388     {
8389       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8390         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8391       return "and{l}\t{%2, %k0|%k0, %2}";
8392     }
8393   return "and{b}\t{%2, %0|%0, %2}";
8395   [(set_attr "type" "alu")
8396    (set_attr "mode" "QI,QI,SI")])
8398 (define_insn "*andqi_2"
8399   [(set (reg FLAGS_REG)
8400         (compare (and:QI
8401                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8402                    (match_operand:QI 2 "general_operand" "qim,qi"))
8403                  (const_int 0)))
8404    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8405         (and:QI (match_dup 1) (match_dup 2)))]
8406   "ix86_match_ccmode (insn, CCNOmode)
8407    && ix86_binary_operator_ok (AND, QImode, operands)"
8408   "and{b}\t{%2, %0|%0, %2}"
8409   [(set_attr "type" "alu")
8410    (set_attr "mode" "QI")])
8412 (define_insn "*andqi_2_slp"
8413   [(set (reg FLAGS_REG)
8414         (compare (and:QI
8415                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8416                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8417                  (const_int 0)))
8418    (set (strict_low_part (match_dup 0))
8419         (and:QI (match_dup 0) (match_dup 1)))]
8420   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8421    && ix86_match_ccmode (insn, CCNOmode)
8422    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8423   "and{b}\t{%1, %0|%0, %1}"
8424   [(set_attr "type" "alu1")
8425    (set_attr "mode" "QI")])
8427 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8428 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8429 ;; for a QImode operand, which of course failed.
8431 (define_insn "andqi_ext_0"
8432   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8433                          (const_int 8)
8434                          (const_int 8))
8435         (and:SI
8436           (zero_extract:SI
8437             (match_operand 1 "ext_register_operand" "0")
8438             (const_int 8)
8439             (const_int 8))
8440           (match_operand 2 "const_int_operand" "n")))
8441    (clobber (reg:CC FLAGS_REG))]
8442   ""
8443   "and{b}\t{%2, %h0|%h0, %2}"
8444   [(set_attr "type" "alu")
8445    (set_attr "length_immediate" "1")
8446    (set_attr "mode" "QI")])
8448 ;; Generated by peephole translating test to and.  This shows up
8449 ;; often in fp comparisons.
8451 (define_insn "*andqi_ext_0_cc"
8452   [(set (reg FLAGS_REG)
8453         (compare
8454           (and:SI
8455             (zero_extract:SI
8456               (match_operand 1 "ext_register_operand" "0")
8457               (const_int 8)
8458               (const_int 8))
8459             (match_operand 2 "const_int_operand" "n"))
8460           (const_int 0)))
8461    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8462                          (const_int 8)
8463                          (const_int 8))
8464         (and:SI
8465           (zero_extract:SI
8466             (match_dup 1)
8467             (const_int 8)
8468             (const_int 8))
8469           (match_dup 2)))]
8470   "ix86_match_ccmode (insn, CCNOmode)"
8471   "and{b}\t{%2, %h0|%h0, %2}"
8472   [(set_attr "type" "alu")
8473    (set_attr "length_immediate" "1")
8474    (set_attr "mode" "QI")])
8476 (define_insn "*andqi_ext_1"
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:QI 2 "general_operand" "Qm"))))
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_1_rex64"
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_extend:SI
8504             (match_operand 2 "ext_register_operand" "Q"))))
8505    (clobber (reg:CC FLAGS_REG))]
8506   "TARGET_64BIT"
8507   "and{b}\t{%2, %h0|%h0, %2}"
8508   [(set_attr "type" "alu")
8509    (set_attr "length_immediate" "0")
8510    (set_attr "mode" "QI")])
8512 (define_insn "*andqi_ext_2"
8513   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8514                          (const_int 8)
8515                          (const_int 8))
8516         (and:SI
8517           (zero_extract:SI
8518             (match_operand 1 "ext_register_operand" "%0")
8519             (const_int 8)
8520             (const_int 8))
8521           (zero_extract:SI
8522             (match_operand 2 "ext_register_operand" "Q")
8523             (const_int 8)
8524             (const_int 8))))
8525    (clobber (reg:CC FLAGS_REG))]
8526   ""
8527   "and{b}\t{%h2, %h0|%h0, %h2}"
8528   [(set_attr "type" "alu")
8529    (set_attr "length_immediate" "0")
8530    (set_attr "mode" "QI")])
8532 ;; Convert wide AND instructions with immediate operand to shorter QImode
8533 ;; equivalents when possible.
8534 ;; Don't do the splitting with memory operands, since it introduces risk
8535 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8536 ;; for size, but that can (should?) be handled by generic code instead.
8537 (define_split
8538   [(set (match_operand 0 "register_operand" "")
8539         (and (match_operand 1 "register_operand" "")
8540              (match_operand 2 "const_int_operand" "")))
8541    (clobber (reg:CC FLAGS_REG))]
8542    "reload_completed
8543     && QI_REG_P (operands[0])
8544     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8545     && !(~INTVAL (operands[2]) & ~(255 << 8))
8546     && GET_MODE (operands[0]) != QImode"
8547   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8548                    (and:SI (zero_extract:SI (match_dup 1)
8549                                             (const_int 8) (const_int 8))
8550                            (match_dup 2)))
8551               (clobber (reg:CC FLAGS_REG))])]
8552   "operands[0] = gen_lowpart (SImode, operands[0]);
8553    operands[1] = gen_lowpart (SImode, operands[1]);
8554    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8556 ;; Since AND can be encoded with sign extended immediate, this is only
8557 ;; profitable when 7th bit is not set.
8558 (define_split
8559   [(set (match_operand 0 "register_operand" "")
8560         (and (match_operand 1 "general_operand" "")
8561              (match_operand 2 "const_int_operand" "")))
8562    (clobber (reg:CC FLAGS_REG))]
8563    "reload_completed
8564     && ANY_QI_REG_P (operands[0])
8565     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8566     && !(~INTVAL (operands[2]) & ~255)
8567     && !(INTVAL (operands[2]) & 128)
8568     && GET_MODE (operands[0]) != QImode"
8569   [(parallel [(set (strict_low_part (match_dup 0))
8570                    (and:QI (match_dup 1)
8571                            (match_dup 2)))
8572               (clobber (reg:CC FLAGS_REG))])]
8573   "operands[0] = gen_lowpart (QImode, operands[0]);
8574    operands[1] = gen_lowpart (QImode, operands[1]);
8575    operands[2] = gen_lowpart (QImode, operands[2]);")
8577 ;; Logical inclusive OR instructions
8579 ;; %%% This used to optimize known byte-wide and operations to memory.
8580 ;; If this is considered useful, it should be done with splitters.
8582 (define_expand "iordi3"
8583   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8584         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8585                 (match_operand:DI 2 "x86_64_general_operand" "")))
8586    (clobber (reg:CC FLAGS_REG))]
8587   "TARGET_64BIT"
8588   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8590 (define_insn "*iordi_1_rex64"
8591   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8592         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8593                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8594    (clobber (reg:CC FLAGS_REG))]
8595   "TARGET_64BIT
8596    && ix86_binary_operator_ok (IOR, DImode, operands)"
8597   "or{q}\t{%2, %0|%0, %2}"
8598   [(set_attr "type" "alu")
8599    (set_attr "mode" "DI")])
8601 (define_insn "*iordi_2_rex64"
8602   [(set (reg FLAGS_REG)
8603         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8604                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8605                  (const_int 0)))
8606    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8607         (ior:DI (match_dup 1) (match_dup 2)))]
8608   "TARGET_64BIT
8609    && ix86_match_ccmode (insn, CCNOmode)
8610    && ix86_binary_operator_ok (IOR, DImode, operands)"
8611   "or{q}\t{%2, %0|%0, %2}"
8612   [(set_attr "type" "alu")
8613    (set_attr "mode" "DI")])
8615 (define_insn "*iordi_3_rex64"
8616   [(set (reg FLAGS_REG)
8617         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8618                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8619                  (const_int 0)))
8620    (clobber (match_scratch:DI 0 "=r"))]
8621   "TARGET_64BIT
8622    && ix86_match_ccmode (insn, CCNOmode)
8623    && ix86_binary_operator_ok (IOR, DImode, operands)"
8624   "or{q}\t{%2, %0|%0, %2}"
8625   [(set_attr "type" "alu")
8626    (set_attr "mode" "DI")])
8629 (define_expand "iorsi3"
8630   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8631         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8632                 (match_operand:SI 2 "general_operand" "")))
8633    (clobber (reg:CC FLAGS_REG))]
8634   ""
8635   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8637 (define_insn "*iorsi_1"
8638   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8639         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8640                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8641    (clobber (reg:CC FLAGS_REG))]
8642   "ix86_binary_operator_ok (IOR, SImode, operands)"
8643   "or{l}\t{%2, %0|%0, %2}"
8644   [(set_attr "type" "alu")
8645    (set_attr "mode" "SI")])
8647 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8648 (define_insn "*iorsi_1_zext"
8649   [(set (match_operand:DI 0 "register_operand" "=rm")
8650         (zero_extend:DI
8651           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8652                   (match_operand:SI 2 "general_operand" "rim"))))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8655   "or{l}\t{%2, %k0|%k0, %2}"
8656   [(set_attr "type" "alu")
8657    (set_attr "mode" "SI")])
8659 (define_insn "*iorsi_1_zext_imm"
8660   [(set (match_operand:DI 0 "register_operand" "=rm")
8661         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8662                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8663    (clobber (reg:CC FLAGS_REG))]
8664   "TARGET_64BIT"
8665   "or{l}\t{%2, %k0|%k0, %2}"
8666   [(set_attr "type" "alu")
8667    (set_attr "mode" "SI")])
8669 (define_insn "*iorsi_2"
8670   [(set (reg FLAGS_REG)
8671         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8672                          (match_operand:SI 2 "general_operand" "rim,ri"))
8673                  (const_int 0)))
8674    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8675         (ior:SI (match_dup 1) (match_dup 2)))]
8676   "ix86_match_ccmode (insn, CCNOmode)
8677    && ix86_binary_operator_ok (IOR, SImode, operands)"
8678   "or{l}\t{%2, %0|%0, %2}"
8679   [(set_attr "type" "alu")
8680    (set_attr "mode" "SI")])
8682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8683 ;; ??? Special case for immediate operand is missing - it is tricky.
8684 (define_insn "*iorsi_2_zext"
8685   [(set (reg FLAGS_REG)
8686         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8687                          (match_operand:SI 2 "general_operand" "rim"))
8688                  (const_int 0)))
8689    (set (match_operand:DI 0 "register_operand" "=r")
8690         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8691   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8692    && ix86_binary_operator_ok (IOR, SImode, operands)"
8693   "or{l}\t{%2, %k0|%k0, %2}"
8694   [(set_attr "type" "alu")
8695    (set_attr "mode" "SI")])
8697 (define_insn "*iorsi_2_zext_imm"
8698   [(set (reg FLAGS_REG)
8699         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8700                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8701                  (const_int 0)))
8702    (set (match_operand:DI 0 "register_operand" "=r")
8703         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8704   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8705    && ix86_binary_operator_ok (IOR, SImode, operands)"
8706   "or{l}\t{%2, %k0|%k0, %2}"
8707   [(set_attr "type" "alu")
8708    (set_attr "mode" "SI")])
8710 (define_insn "*iorsi_3"
8711   [(set (reg FLAGS_REG)
8712         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8713                          (match_operand:SI 2 "general_operand" "rim"))
8714                  (const_int 0)))
8715    (clobber (match_scratch:SI 0 "=r"))]
8716   "ix86_match_ccmode (insn, CCNOmode)
8717    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8718   "or{l}\t{%2, %0|%0, %2}"
8719   [(set_attr "type" "alu")
8720    (set_attr "mode" "SI")])
8722 (define_expand "iorhi3"
8723   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8724         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8725                 (match_operand:HI 2 "general_operand" "")))
8726    (clobber (reg:CC FLAGS_REG))]
8727   "TARGET_HIMODE_MATH"
8728   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8730 (define_insn "*iorhi_1"
8731   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8732         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8733                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8734    (clobber (reg:CC FLAGS_REG))]
8735   "ix86_binary_operator_ok (IOR, HImode, operands)"
8736   "or{w}\t{%2, %0|%0, %2}"
8737   [(set_attr "type" "alu")
8738    (set_attr "mode" "HI")])
8740 (define_insn "*iorhi_2"
8741   [(set (reg FLAGS_REG)
8742         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8743                          (match_operand:HI 2 "general_operand" "rim,ri"))
8744                  (const_int 0)))
8745    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8746         (ior:HI (match_dup 1) (match_dup 2)))]
8747   "ix86_match_ccmode (insn, CCNOmode)
8748    && ix86_binary_operator_ok (IOR, HImode, operands)"
8749   "or{w}\t{%2, %0|%0, %2}"
8750   [(set_attr "type" "alu")
8751    (set_attr "mode" "HI")])
8753 (define_insn "*iorhi_3"
8754   [(set (reg FLAGS_REG)
8755         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8756                          (match_operand:HI 2 "general_operand" "rim"))
8757                  (const_int 0)))
8758    (clobber (match_scratch:HI 0 "=r"))]
8759   "ix86_match_ccmode (insn, CCNOmode)
8760    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8761   "or{w}\t{%2, %0|%0, %2}"
8762   [(set_attr "type" "alu")
8763    (set_attr "mode" "HI")])
8765 (define_expand "iorqi3"
8766   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8767         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8768                 (match_operand:QI 2 "general_operand" "")))
8769    (clobber (reg:CC FLAGS_REG))]
8770   "TARGET_QIMODE_MATH"
8771   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8773 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8774 (define_insn "*iorqi_1"
8775   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8776         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8777                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8778    (clobber (reg:CC FLAGS_REG))]
8779   "ix86_binary_operator_ok (IOR, QImode, operands)"
8780   "@
8781    or{b}\t{%2, %0|%0, %2}
8782    or{b}\t{%2, %0|%0, %2}
8783    or{l}\t{%k2, %k0|%k0, %k2}"
8784   [(set_attr "type" "alu")
8785    (set_attr "mode" "QI,QI,SI")])
8787 (define_insn "*iorqi_1_slp"
8788   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8789         (ior:QI (match_dup 0)
8790                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8791    (clobber (reg:CC FLAGS_REG))]
8792   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8793    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8794   "or{b}\t{%1, %0|%0, %1}"
8795   [(set_attr "type" "alu1")
8796    (set_attr "mode" "QI")])
8798 (define_insn "*iorqi_2"
8799   [(set (reg FLAGS_REG)
8800         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8801                          (match_operand:QI 2 "general_operand" "qim,qi"))
8802                  (const_int 0)))
8803    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8804         (ior:QI (match_dup 1) (match_dup 2)))]
8805   "ix86_match_ccmode (insn, CCNOmode)
8806    && ix86_binary_operator_ok (IOR, QImode, operands)"
8807   "or{b}\t{%2, %0|%0, %2}"
8808   [(set_attr "type" "alu")
8809    (set_attr "mode" "QI")])
8811 (define_insn "*iorqi_2_slp"
8812   [(set (reg FLAGS_REG)
8813         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8814                          (match_operand:QI 1 "general_operand" "qim,qi"))
8815                  (const_int 0)))
8816    (set (strict_low_part (match_dup 0))
8817         (ior:QI (match_dup 0) (match_dup 1)))]
8818   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8819    && ix86_match_ccmode (insn, CCNOmode)
8820    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8821   "or{b}\t{%1, %0|%0, %1}"
8822   [(set_attr "type" "alu1")
8823    (set_attr "mode" "QI")])
8825 (define_insn "*iorqi_3"
8826   [(set (reg FLAGS_REG)
8827         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8828                          (match_operand:QI 2 "general_operand" "qim"))
8829                  (const_int 0)))
8830    (clobber (match_scratch:QI 0 "=q"))]
8831   "ix86_match_ccmode (insn, CCNOmode)
8832    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8833   "or{b}\t{%2, %0|%0, %2}"
8834   [(set_attr "type" "alu")
8835    (set_attr "mode" "QI")])
8837 (define_insn "iorqi_ext_0"
8838   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8839                          (const_int 8)
8840                          (const_int 8))
8841         (ior:SI
8842           (zero_extract:SI
8843             (match_operand 1 "ext_register_operand" "0")
8844             (const_int 8)
8845             (const_int 8))
8846           (match_operand 2 "const_int_operand" "n")))
8847    (clobber (reg:CC FLAGS_REG))]
8848   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8849   "or{b}\t{%2, %h0|%h0, %2}"
8850   [(set_attr "type" "alu")
8851    (set_attr "length_immediate" "1")
8852    (set_attr "mode" "QI")])
8854 (define_insn "*iorqi_ext_1"
8855   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8856                          (const_int 8)
8857                          (const_int 8))
8858         (ior:SI
8859           (zero_extract:SI
8860             (match_operand 1 "ext_register_operand" "0")
8861             (const_int 8)
8862             (const_int 8))
8863           (zero_extend:SI
8864             (match_operand:QI 2 "general_operand" "Qm"))))
8865    (clobber (reg:CC FLAGS_REG))]
8866   "!TARGET_64BIT
8867    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8868   "or{b}\t{%2, %h0|%h0, %2}"
8869   [(set_attr "type" "alu")
8870    (set_attr "length_immediate" "0")
8871    (set_attr "mode" "QI")])
8873 (define_insn "*iorqi_ext_1_rex64"
8874   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8875                          (const_int 8)
8876                          (const_int 8))
8877         (ior:SI
8878           (zero_extract:SI
8879             (match_operand 1 "ext_register_operand" "0")
8880             (const_int 8)
8881             (const_int 8))
8882           (zero_extend:SI
8883             (match_operand 2 "ext_register_operand" "Q"))))
8884    (clobber (reg:CC FLAGS_REG))]
8885   "TARGET_64BIT
8886    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8887   "or{b}\t{%2, %h0|%h0, %2}"
8888   [(set_attr "type" "alu")
8889    (set_attr "length_immediate" "0")
8890    (set_attr "mode" "QI")])
8892 (define_insn "*iorqi_ext_2"
8893   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8894                          (const_int 8)
8895                          (const_int 8))
8896         (ior:SI
8897           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8898                            (const_int 8)
8899                            (const_int 8))
8900           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8901                            (const_int 8)
8902                            (const_int 8))))
8903    (clobber (reg:CC FLAGS_REG))]
8904   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8905   "ior{b}\t{%h2, %h0|%h0, %h2}"
8906   [(set_attr "type" "alu")
8907    (set_attr "length_immediate" "0")
8908    (set_attr "mode" "QI")])
8910 (define_split
8911   [(set (match_operand 0 "register_operand" "")
8912         (ior (match_operand 1 "register_operand" "")
8913              (match_operand 2 "const_int_operand" "")))
8914    (clobber (reg:CC FLAGS_REG))]
8915    "reload_completed
8916     && QI_REG_P (operands[0])
8917     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8918     && !(INTVAL (operands[2]) & ~(255 << 8))
8919     && GET_MODE (operands[0]) != QImode"
8920   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8921                    (ior:SI (zero_extract:SI (match_dup 1)
8922                                             (const_int 8) (const_int 8))
8923                            (match_dup 2)))
8924               (clobber (reg:CC FLAGS_REG))])]
8925   "operands[0] = gen_lowpart (SImode, operands[0]);
8926    operands[1] = gen_lowpart (SImode, operands[1]);
8927    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8929 ;; Since OR can be encoded with sign extended immediate, this is only
8930 ;; profitable when 7th bit is set.
8931 (define_split
8932   [(set (match_operand 0 "register_operand" "")
8933         (ior (match_operand 1 "general_operand" "")
8934              (match_operand 2 "const_int_operand" "")))
8935    (clobber (reg:CC FLAGS_REG))]
8936    "reload_completed
8937     && ANY_QI_REG_P (operands[0])
8938     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8939     && !(INTVAL (operands[2]) & ~255)
8940     && (INTVAL (operands[2]) & 128)
8941     && GET_MODE (operands[0]) != QImode"
8942   [(parallel [(set (strict_low_part (match_dup 0))
8943                    (ior:QI (match_dup 1)
8944                            (match_dup 2)))
8945               (clobber (reg:CC FLAGS_REG))])]
8946   "operands[0] = gen_lowpart (QImode, operands[0]);
8947    operands[1] = gen_lowpart (QImode, operands[1]);
8948    operands[2] = gen_lowpart (QImode, operands[2]);")
8950 ;; Logical XOR instructions
8952 ;; %%% This used to optimize known byte-wide and operations to memory.
8953 ;; If this is considered useful, it should be done with splitters.
8955 (define_expand "xordi3"
8956   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8957         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8958                 (match_operand:DI 2 "x86_64_general_operand" "")))
8959    (clobber (reg:CC FLAGS_REG))]
8960   "TARGET_64BIT"
8961   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8963 (define_insn "*xordi_1_rex64"
8964   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8965         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8966                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8967    (clobber (reg:CC FLAGS_REG))]
8968   "TARGET_64BIT
8969    && ix86_binary_operator_ok (XOR, DImode, operands)"
8970   "@
8971    xor{q}\t{%2, %0|%0, %2}
8972    xor{q}\t{%2, %0|%0, %2}"
8973   [(set_attr "type" "alu")
8974    (set_attr "mode" "DI,DI")])
8976 (define_insn "*xordi_2_rex64"
8977   [(set (reg FLAGS_REG)
8978         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8979                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8980                  (const_int 0)))
8981    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8982         (xor:DI (match_dup 1) (match_dup 2)))]
8983   "TARGET_64BIT
8984    && ix86_match_ccmode (insn, CCNOmode)
8985    && ix86_binary_operator_ok (XOR, DImode, operands)"
8986   "@
8987    xor{q}\t{%2, %0|%0, %2}
8988    xor{q}\t{%2, %0|%0, %2}"
8989   [(set_attr "type" "alu")
8990    (set_attr "mode" "DI,DI")])
8992 (define_insn "*xordi_3_rex64"
8993   [(set (reg FLAGS_REG)
8994         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8995                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8996                  (const_int 0)))
8997    (clobber (match_scratch:DI 0 "=r"))]
8998   "TARGET_64BIT
8999    && ix86_match_ccmode (insn, CCNOmode)
9000    && ix86_binary_operator_ok (XOR, DImode, operands)"
9001   "xor{q}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "DI")])
9005 (define_expand "xorsi3"
9006   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9007         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9008                 (match_operand:SI 2 "general_operand" "")))
9009    (clobber (reg:CC FLAGS_REG))]
9010   ""
9011   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9013 (define_insn "*xorsi_1"
9014   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9015         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9016                 (match_operand:SI 2 "general_operand" "ri,rm")))
9017    (clobber (reg:CC FLAGS_REG))]
9018   "ix86_binary_operator_ok (XOR, SImode, operands)"
9019   "xor{l}\t{%2, %0|%0, %2}"
9020   [(set_attr "type" "alu")
9021    (set_attr "mode" "SI")])
9023 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9024 ;; Add speccase for immediates
9025 (define_insn "*xorsi_1_zext"
9026   [(set (match_operand:DI 0 "register_operand" "=r")
9027         (zero_extend:DI
9028           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9029                   (match_operand:SI 2 "general_operand" "rim"))))
9030    (clobber (reg:CC FLAGS_REG))]
9031   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9032   "xor{l}\t{%2, %k0|%k0, %2}"
9033   [(set_attr "type" "alu")
9034    (set_attr "mode" "SI")])
9036 (define_insn "*xorsi_1_zext_imm"
9037   [(set (match_operand:DI 0 "register_operand" "=r")
9038         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9039                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9040    (clobber (reg:CC FLAGS_REG))]
9041   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9042   "xor{l}\t{%2, %k0|%k0, %2}"
9043   [(set_attr "type" "alu")
9044    (set_attr "mode" "SI")])
9046 (define_insn "*xorsi_2"
9047   [(set (reg FLAGS_REG)
9048         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9049                          (match_operand:SI 2 "general_operand" "rim,ri"))
9050                  (const_int 0)))
9051    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9052         (xor:SI (match_dup 1) (match_dup 2)))]
9053   "ix86_match_ccmode (insn, CCNOmode)
9054    && ix86_binary_operator_ok (XOR, SImode, operands)"
9055   "xor{l}\t{%2, %0|%0, %2}"
9056   [(set_attr "type" "alu")
9057    (set_attr "mode" "SI")])
9059 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9060 ;; ??? Special case for immediate operand is missing - it is tricky.
9061 (define_insn "*xorsi_2_zext"
9062   [(set (reg FLAGS_REG)
9063         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9064                          (match_operand:SI 2 "general_operand" "rim"))
9065                  (const_int 0)))
9066    (set (match_operand:DI 0 "register_operand" "=r")
9067         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9068   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9069    && ix86_binary_operator_ok (XOR, SImode, operands)"
9070   "xor{l}\t{%2, %k0|%k0, %2}"
9071   [(set_attr "type" "alu")
9072    (set_attr "mode" "SI")])
9074 (define_insn "*xorsi_2_zext_imm"
9075   [(set (reg FLAGS_REG)
9076         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9077                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9078                  (const_int 0)))
9079    (set (match_operand:DI 0 "register_operand" "=r")
9080         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9081   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9082    && ix86_binary_operator_ok (XOR, SImode, operands)"
9083   "xor{l}\t{%2, %k0|%k0, %2}"
9084   [(set_attr "type" "alu")
9085    (set_attr "mode" "SI")])
9087 (define_insn "*xorsi_3"
9088   [(set (reg FLAGS_REG)
9089         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9090                          (match_operand:SI 2 "general_operand" "rim"))
9091                  (const_int 0)))
9092    (clobber (match_scratch:SI 0 "=r"))]
9093   "ix86_match_ccmode (insn, CCNOmode)
9094    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9095   "xor{l}\t{%2, %0|%0, %2}"
9096   [(set_attr "type" "alu")
9097    (set_attr "mode" "SI")])
9099 (define_expand "xorhi3"
9100   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9101         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9102                 (match_operand:HI 2 "general_operand" "")))
9103    (clobber (reg:CC FLAGS_REG))]
9104   "TARGET_HIMODE_MATH"
9105   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9107 (define_insn "*xorhi_1"
9108   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9109         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9110                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9111    (clobber (reg:CC FLAGS_REG))]
9112   "ix86_binary_operator_ok (XOR, HImode, operands)"
9113   "xor{w}\t{%2, %0|%0, %2}"
9114   [(set_attr "type" "alu")
9115    (set_attr "mode" "HI")])
9117 (define_insn "*xorhi_2"
9118   [(set (reg FLAGS_REG)
9119         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9120                          (match_operand:HI 2 "general_operand" "rim,ri"))
9121                  (const_int 0)))
9122    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9123         (xor:HI (match_dup 1) (match_dup 2)))]
9124   "ix86_match_ccmode (insn, CCNOmode)
9125    && ix86_binary_operator_ok (XOR, HImode, operands)"
9126   "xor{w}\t{%2, %0|%0, %2}"
9127   [(set_attr "type" "alu")
9128    (set_attr "mode" "HI")])
9130 (define_insn "*xorhi_3"
9131   [(set (reg FLAGS_REG)
9132         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9133                          (match_operand:HI 2 "general_operand" "rim"))
9134                  (const_int 0)))
9135    (clobber (match_scratch:HI 0 "=r"))]
9136   "ix86_match_ccmode (insn, CCNOmode)
9137    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9138   "xor{w}\t{%2, %0|%0, %2}"
9139   [(set_attr "type" "alu")
9140    (set_attr "mode" "HI")])
9142 (define_expand "xorqi3"
9143   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9144         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9145                 (match_operand:QI 2 "general_operand" "")))
9146    (clobber (reg:CC FLAGS_REG))]
9147   "TARGET_QIMODE_MATH"
9148   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9150 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9151 (define_insn "*xorqi_1"
9152   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9153         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9154                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9155    (clobber (reg:CC FLAGS_REG))]
9156   "ix86_binary_operator_ok (XOR, QImode, operands)"
9157   "@
9158    xor{b}\t{%2, %0|%0, %2}
9159    xor{b}\t{%2, %0|%0, %2}
9160    xor{l}\t{%k2, %k0|%k0, %k2}"
9161   [(set_attr "type" "alu")
9162    (set_attr "mode" "QI,QI,SI")])
9164 (define_insn "*xorqi_1_slp"
9165   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9166         (xor:QI (match_dup 0)
9167                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9168    (clobber (reg:CC FLAGS_REG))]
9169   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9170    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9171   "xor{b}\t{%1, %0|%0, %1}"
9172   [(set_attr "type" "alu1")
9173    (set_attr "mode" "QI")])
9175 (define_insn "xorqi_ext_0"
9176   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9177                          (const_int 8)
9178                          (const_int 8))
9179         (xor:SI
9180           (zero_extract:SI
9181             (match_operand 1 "ext_register_operand" "0")
9182             (const_int 8)
9183             (const_int 8))
9184           (match_operand 2 "const_int_operand" "n")))
9185    (clobber (reg:CC FLAGS_REG))]
9186   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9187   "xor{b}\t{%2, %h0|%h0, %2}"
9188   [(set_attr "type" "alu")
9189    (set_attr "length_immediate" "1")
9190    (set_attr "mode" "QI")])
9192 (define_insn "*xorqi_ext_1"
9193   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9194                          (const_int 8)
9195                          (const_int 8))
9196         (xor:SI
9197           (zero_extract:SI
9198             (match_operand 1 "ext_register_operand" "0")
9199             (const_int 8)
9200             (const_int 8))
9201           (zero_extend:SI
9202             (match_operand:QI 2 "general_operand" "Qm"))))
9203    (clobber (reg:CC FLAGS_REG))]
9204   "!TARGET_64BIT
9205    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9206   "xor{b}\t{%2, %h0|%h0, %2}"
9207   [(set_attr "type" "alu")
9208    (set_attr "length_immediate" "0")
9209    (set_attr "mode" "QI")])
9211 (define_insn "*xorqi_ext_1_rex64"
9212   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9213                          (const_int 8)
9214                          (const_int 8))
9215         (xor:SI
9216           (zero_extract:SI
9217             (match_operand 1 "ext_register_operand" "0")
9218             (const_int 8)
9219             (const_int 8))
9220           (zero_extend:SI
9221             (match_operand 2 "ext_register_operand" "Q"))))
9222    (clobber (reg:CC FLAGS_REG))]
9223   "TARGET_64BIT
9224    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9225   "xor{b}\t{%2, %h0|%h0, %2}"
9226   [(set_attr "type" "alu")
9227    (set_attr "length_immediate" "0")
9228    (set_attr "mode" "QI")])
9230 (define_insn "*xorqi_ext_2"
9231   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9232                          (const_int 8)
9233                          (const_int 8))
9234         (xor:SI
9235           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9236                            (const_int 8)
9237                            (const_int 8))
9238           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9239                            (const_int 8)
9240                            (const_int 8))))
9241    (clobber (reg:CC FLAGS_REG))]
9242   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9243   "xor{b}\t{%h2, %h0|%h0, %h2}"
9244   [(set_attr "type" "alu")
9245    (set_attr "length_immediate" "0")
9246    (set_attr "mode" "QI")])
9248 (define_insn "*xorqi_cc_1"
9249   [(set (reg FLAGS_REG)
9250         (compare
9251           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9252                   (match_operand:QI 2 "general_operand" "qim,qi"))
9253           (const_int 0)))
9254    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9255         (xor:QI (match_dup 1) (match_dup 2)))]
9256   "ix86_match_ccmode (insn, CCNOmode)
9257    && ix86_binary_operator_ok (XOR, QImode, operands)"
9258   "xor{b}\t{%2, %0|%0, %2}"
9259   [(set_attr "type" "alu")
9260    (set_attr "mode" "QI")])
9262 (define_insn "*xorqi_2_slp"
9263   [(set (reg FLAGS_REG)
9264         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9265                          (match_operand:QI 1 "general_operand" "qim,qi"))
9266                  (const_int 0)))
9267    (set (strict_low_part (match_dup 0))
9268         (xor:QI (match_dup 0) (match_dup 1)))]
9269   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9270    && ix86_match_ccmode (insn, CCNOmode)
9271    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9272   "xor{b}\t{%1, %0|%0, %1}"
9273   [(set_attr "type" "alu1")
9274    (set_attr "mode" "QI")])
9276 (define_insn "*xorqi_cc_2"
9277   [(set (reg FLAGS_REG)
9278         (compare
9279           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9280                   (match_operand:QI 2 "general_operand" "qim"))
9281           (const_int 0)))
9282    (clobber (match_scratch:QI 0 "=q"))]
9283   "ix86_match_ccmode (insn, CCNOmode)
9284    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9285   "xor{b}\t{%2, %0|%0, %2}"
9286   [(set_attr "type" "alu")
9287    (set_attr "mode" "QI")])
9289 (define_insn "*xorqi_cc_ext_1"
9290   [(set (reg FLAGS_REG)
9291         (compare
9292           (xor:SI
9293             (zero_extract:SI
9294               (match_operand 1 "ext_register_operand" "0")
9295               (const_int 8)
9296               (const_int 8))
9297             (match_operand:QI 2 "general_operand" "qmn"))
9298           (const_int 0)))
9299    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9300                          (const_int 8)
9301                          (const_int 8))
9302         (xor:SI
9303           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9304           (match_dup 2)))]
9305   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9306   "xor{b}\t{%2, %h0|%h0, %2}"
9307   [(set_attr "type" "alu")
9308    (set_attr "mode" "QI")])
9310 (define_insn "*xorqi_cc_ext_1_rex64"
9311   [(set (reg FLAGS_REG)
9312         (compare
9313           (xor:SI
9314             (zero_extract:SI
9315               (match_operand 1 "ext_register_operand" "0")
9316               (const_int 8)
9317               (const_int 8))
9318             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9319           (const_int 0)))
9320    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9321                          (const_int 8)
9322                          (const_int 8))
9323         (xor:SI
9324           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9325           (match_dup 2)))]
9326   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9327   "xor{b}\t{%2, %h0|%h0, %2}"
9328   [(set_attr "type" "alu")
9329    (set_attr "mode" "QI")])
9331 (define_expand "xorqi_cc_ext_1"
9332   [(parallel [
9333      (set (reg:CCNO FLAGS_REG)
9334           (compare:CCNO
9335             (xor:SI
9336               (zero_extract:SI
9337                 (match_operand 1 "ext_register_operand" "")
9338                 (const_int 8)
9339                 (const_int 8))
9340               (match_operand:QI 2 "general_operand" ""))
9341             (const_int 0)))
9342      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9343                            (const_int 8)
9344                            (const_int 8))
9345           (xor:SI
9346             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9347             (match_dup 2)))])]
9348   ""
9349   "")
9351 (define_split
9352   [(set (match_operand 0 "register_operand" "")
9353         (xor (match_operand 1 "register_operand" "")
9354              (match_operand 2 "const_int_operand" "")))
9355    (clobber (reg:CC FLAGS_REG))]
9356    "reload_completed
9357     && QI_REG_P (operands[0])
9358     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9359     && !(INTVAL (operands[2]) & ~(255 << 8))
9360     && GET_MODE (operands[0]) != QImode"
9361   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9362                    (xor:SI (zero_extract:SI (match_dup 1)
9363                                             (const_int 8) (const_int 8))
9364                            (match_dup 2)))
9365               (clobber (reg:CC FLAGS_REG))])]
9366   "operands[0] = gen_lowpart (SImode, operands[0]);
9367    operands[1] = gen_lowpart (SImode, operands[1]);
9368    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9370 ;; Since XOR can be encoded with sign extended immediate, this is only
9371 ;; profitable when 7th bit is set.
9372 (define_split
9373   [(set (match_operand 0 "register_operand" "")
9374         (xor (match_operand 1 "general_operand" "")
9375              (match_operand 2 "const_int_operand" "")))
9376    (clobber (reg:CC FLAGS_REG))]
9377    "reload_completed
9378     && ANY_QI_REG_P (operands[0])
9379     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9380     && !(INTVAL (operands[2]) & ~255)
9381     && (INTVAL (operands[2]) & 128)
9382     && GET_MODE (operands[0]) != QImode"
9383   [(parallel [(set (strict_low_part (match_dup 0))
9384                    (xor:QI (match_dup 1)
9385                            (match_dup 2)))
9386               (clobber (reg:CC FLAGS_REG))])]
9387   "operands[0] = gen_lowpart (QImode, operands[0]);
9388    operands[1] = gen_lowpart (QImode, operands[1]);
9389    operands[2] = gen_lowpart (QImode, operands[2]);")
9391 ;; Negation instructions
9393 (define_expand "negti2"
9394   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9395                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9396               (clobber (reg:CC FLAGS_REG))])]
9397   "TARGET_64BIT"
9398   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9400 (define_insn "*negti2_1"
9401   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9402         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9403    (clobber (reg:CC FLAGS_REG))]
9404   "TARGET_64BIT
9405    && ix86_unary_operator_ok (NEG, TImode, operands)"
9406   "#")
9408 (define_split
9409   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9410         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9411    (clobber (reg:CC FLAGS_REG))]
9412   "TARGET_64BIT && reload_completed"
9413   [(parallel
9414     [(set (reg:CCZ FLAGS_REG)
9415           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9416      (set (match_dup 0) (neg:DI (match_dup 2)))])
9417    (parallel
9418     [(set (match_dup 1)
9419           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9420                             (match_dup 3))
9421                    (const_int 0)))
9422      (clobber (reg:CC FLAGS_REG))])
9423    (parallel
9424     [(set (match_dup 1)
9425           (neg:DI (match_dup 1)))
9426      (clobber (reg:CC FLAGS_REG))])]
9427   "split_ti (operands+1, 1, operands+2, operands+3);
9428    split_ti (operands+0, 1, operands+0, operands+1);")
9430 (define_expand "negdi2"
9431   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9432                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9433               (clobber (reg:CC FLAGS_REG))])]
9434   ""
9435   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9437 (define_insn "*negdi2_1"
9438   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9439         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9440    (clobber (reg:CC FLAGS_REG))]
9441   "!TARGET_64BIT
9442    && ix86_unary_operator_ok (NEG, DImode, operands)"
9443   "#")
9445 (define_split
9446   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9447         (neg:DI (match_operand:DI 1 "general_operand" "")))
9448    (clobber (reg:CC FLAGS_REG))]
9449   "!TARGET_64BIT && reload_completed"
9450   [(parallel
9451     [(set (reg:CCZ FLAGS_REG)
9452           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9453      (set (match_dup 0) (neg:SI (match_dup 2)))])
9454    (parallel
9455     [(set (match_dup 1)
9456           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9457                             (match_dup 3))
9458                    (const_int 0)))
9459      (clobber (reg:CC FLAGS_REG))])
9460    (parallel
9461     [(set (match_dup 1)
9462           (neg:SI (match_dup 1)))
9463      (clobber (reg:CC FLAGS_REG))])]
9464   "split_di (operands+1, 1, operands+2, operands+3);
9465    split_di (operands+0, 1, operands+0, operands+1);")
9467 (define_insn "*negdi2_1_rex64"
9468   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9469         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9470    (clobber (reg:CC FLAGS_REG))]
9471   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9472   "neg{q}\t%0"
9473   [(set_attr "type" "negnot")
9474    (set_attr "mode" "DI")])
9476 ;; The problem with neg is that it does not perform (compare x 0),
9477 ;; it really performs (compare 0 x), which leaves us with the zero
9478 ;; flag being the only useful item.
9480 (define_insn "*negdi2_cmpz_rex64"
9481   [(set (reg:CCZ FLAGS_REG)
9482         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9483                      (const_int 0)))
9484    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9485         (neg:DI (match_dup 1)))]
9486   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9487   "neg{q}\t%0"
9488   [(set_attr "type" "negnot")
9489    (set_attr "mode" "DI")])
9492 (define_expand "negsi2"
9493   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9494                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9495               (clobber (reg:CC FLAGS_REG))])]
9496   ""
9497   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9499 (define_insn "*negsi2_1"
9500   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9501         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9502    (clobber (reg:CC FLAGS_REG))]
9503   "ix86_unary_operator_ok (NEG, SImode, operands)"
9504   "neg{l}\t%0"
9505   [(set_attr "type" "negnot")
9506    (set_attr "mode" "SI")])
9508 ;; Combine is quite creative about this pattern.
9509 (define_insn "*negsi2_1_zext"
9510   [(set (match_operand:DI 0 "register_operand" "=r")
9511         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9512                                         (const_int 32)))
9513                      (const_int 32)))
9514    (clobber (reg:CC FLAGS_REG))]
9515   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9516   "neg{l}\t%k0"
9517   [(set_attr "type" "negnot")
9518    (set_attr "mode" "SI")])
9520 ;; The problem with neg is that it does not perform (compare x 0),
9521 ;; it really performs (compare 0 x), which leaves us with the zero
9522 ;; flag being the only useful item.
9524 (define_insn "*negsi2_cmpz"
9525   [(set (reg:CCZ FLAGS_REG)
9526         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9527                      (const_int 0)))
9528    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9529         (neg:SI (match_dup 1)))]
9530   "ix86_unary_operator_ok (NEG, SImode, operands)"
9531   "neg{l}\t%0"
9532   [(set_attr "type" "negnot")
9533    (set_attr "mode" "SI")])
9535 (define_insn "*negsi2_cmpz_zext"
9536   [(set (reg:CCZ FLAGS_REG)
9537         (compare:CCZ (lshiftrt:DI
9538                        (neg:DI (ashift:DI
9539                                  (match_operand:DI 1 "register_operand" "0")
9540                                  (const_int 32)))
9541                        (const_int 32))
9542                      (const_int 0)))
9543    (set (match_operand:DI 0 "register_operand" "=r")
9544         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9545                                         (const_int 32)))
9546                      (const_int 32)))]
9547   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9548   "neg{l}\t%k0"
9549   [(set_attr "type" "negnot")
9550    (set_attr "mode" "SI")])
9552 (define_expand "neghi2"
9553   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9554                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9555               (clobber (reg:CC FLAGS_REG))])]
9556   "TARGET_HIMODE_MATH"
9557   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9559 (define_insn "*neghi2_1"
9560   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9561         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9562    (clobber (reg:CC FLAGS_REG))]
9563   "ix86_unary_operator_ok (NEG, HImode, operands)"
9564   "neg{w}\t%0"
9565   [(set_attr "type" "negnot")
9566    (set_attr "mode" "HI")])
9568 (define_insn "*neghi2_cmpz"
9569   [(set (reg:CCZ FLAGS_REG)
9570         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9571                      (const_int 0)))
9572    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9573         (neg:HI (match_dup 1)))]
9574   "ix86_unary_operator_ok (NEG, HImode, operands)"
9575   "neg{w}\t%0"
9576   [(set_attr "type" "negnot")
9577    (set_attr "mode" "HI")])
9579 (define_expand "negqi2"
9580   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9581                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9582               (clobber (reg:CC FLAGS_REG))])]
9583   "TARGET_QIMODE_MATH"
9584   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9586 (define_insn "*negqi2_1"
9587   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9588         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9589    (clobber (reg:CC FLAGS_REG))]
9590   "ix86_unary_operator_ok (NEG, QImode, operands)"
9591   "neg{b}\t%0"
9592   [(set_attr "type" "negnot")
9593    (set_attr "mode" "QI")])
9595 (define_insn "*negqi2_cmpz"
9596   [(set (reg:CCZ FLAGS_REG)
9597         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9598                      (const_int 0)))
9599    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9600         (neg:QI (match_dup 1)))]
9601   "ix86_unary_operator_ok (NEG, QImode, operands)"
9602   "neg{b}\t%0"
9603   [(set_attr "type" "negnot")
9604    (set_attr "mode" "QI")])
9606 ;; Changing of sign for FP values is doable using integer unit too.
9608 (define_expand "negsf2"
9609   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9610         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9611   "TARGET_80387 || TARGET_SSE_MATH"
9612   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9614 (define_expand "abssf2"
9615   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9616         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9617   "TARGET_80387 || TARGET_SSE_MATH"
9618   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9620 (define_insn "*absnegsf2_mixed"
9621   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9622         (match_operator:SF 3 "absneg_operator"
9623           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9624    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9625    (clobber (reg:CC FLAGS_REG))]
9626   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9627    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9628   "#")
9630 (define_insn "*absnegsf2_sse"
9631   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9632         (match_operator:SF 3 "absneg_operator"
9633           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9634    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9635    (clobber (reg:CC FLAGS_REG))]
9636   "TARGET_SSE_MATH
9637    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9638   "#")
9640 (define_insn "*absnegsf2_i387"
9641   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9642         (match_operator:SF 3 "absneg_operator"
9643           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9644    (use (match_operand 2 "" ""))
9645    (clobber (reg:CC FLAGS_REG))]
9646   "TARGET_80387 && !TARGET_SSE_MATH
9647    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9648   "#")
9650 (define_expand "copysignsf3"
9651   [(match_operand:SF 0 "register_operand" "")
9652    (match_operand:SF 1 "nonmemory_operand" "")
9653    (match_operand:SF 2 "register_operand" "")]
9654   "TARGET_SSE_MATH"
9656   ix86_expand_copysign (operands);
9657   DONE;
9660 (define_insn_and_split "copysignsf3_const"
9661   [(set (match_operand:SF 0 "register_operand"          "=x")
9662         (unspec:SF
9663           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9664            (match_operand:SF 2 "register_operand"       "0")
9665            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9666           UNSPEC_COPYSIGN))]
9667   "TARGET_SSE_MATH"
9668   "#"
9669   "&& reload_completed"
9670   [(const_int 0)]
9672   ix86_split_copysign_const (operands);
9673   DONE;
9676 (define_insn "copysignsf3_var"
9677   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9678         (unspec:SF
9679           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9680            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9681            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9682            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9683           UNSPEC_COPYSIGN))
9684    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9685   "TARGET_SSE_MATH"
9686   "#")
9688 (define_split
9689   [(set (match_operand:SF 0 "register_operand" "")
9690         (unspec:SF
9691           [(match_operand:SF 2 "register_operand" "")
9692            (match_operand:SF 3 "register_operand" "")
9693            (match_operand:V4SF 4 "" "")
9694            (match_operand:V4SF 5 "" "")]
9695           UNSPEC_COPYSIGN))
9696    (clobber (match_scratch:V4SF 1 ""))]
9697   "TARGET_SSE_MATH && reload_completed"
9698   [(const_int 0)]
9700   ix86_split_copysign_var (operands);
9701   DONE;
9704 (define_expand "negdf2"
9705   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9706         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9707   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9708   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9710 (define_expand "absdf2"
9711   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9712         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9713   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9714   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9716 (define_insn "*absnegdf2_mixed"
9717   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
9718         (match_operator:DF 3 "absneg_operator"
9719           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9720    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
9721    (clobber (reg:CC FLAGS_REG))]
9722   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9723    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9724   "#")
9726 (define_insn "*absnegdf2_sse"
9727   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
9728         (match_operator:DF 3 "absneg_operator"
9729           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9730    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
9731    (clobber (reg:CC FLAGS_REG))]
9732   "TARGET_SSE2 && TARGET_SSE_MATH
9733    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9734   "#")
9736 (define_insn "*absnegdf2_i387"
9737   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9738         (match_operator:DF 3 "absneg_operator"
9739           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9740    (use (match_operand 2 "" ""))
9741    (clobber (reg:CC FLAGS_REG))]
9742   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9743    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9744   "#")
9746 (define_expand "copysigndf3"
9747   [(match_operand:DF 0 "register_operand" "")
9748    (match_operand:DF 1 "nonmemory_operand" "")
9749    (match_operand:DF 2 "register_operand" "")]
9750   "TARGET_SSE2 && TARGET_SSE_MATH"
9752   ix86_expand_copysign (operands);
9753   DONE;
9756 (define_insn_and_split "copysigndf3_const"
9757   [(set (match_operand:DF 0 "register_operand"          "=x")
9758         (unspec:DF
9759           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9760            (match_operand:DF 2 "register_operand"       "0")
9761            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9762           UNSPEC_COPYSIGN))]
9763   "TARGET_SSE2 && TARGET_SSE_MATH"
9764   "#"
9765   "&& reload_completed"
9766   [(const_int 0)]
9768   ix86_split_copysign_const (operands);
9769   DONE;
9772 (define_insn "copysigndf3_var"
9773   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9774         (unspec:DF
9775           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9776            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9777            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9778            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9779           UNSPEC_COPYSIGN))
9780    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9781   "TARGET_SSE2 && TARGET_SSE_MATH"
9782   "#")
9784 (define_split
9785   [(set (match_operand:DF 0 "register_operand" "")
9786         (unspec:DF
9787           [(match_operand:DF 2 "register_operand" "")
9788            (match_operand:DF 3 "register_operand" "")
9789            (match_operand:V2DF 4 "" "")
9790            (match_operand:V2DF 5 "" "")]
9791           UNSPEC_COPYSIGN))
9792    (clobber (match_scratch:V2DF 1 ""))]
9793   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9794   [(const_int 0)]
9796   ix86_split_copysign_var (operands);
9797   DONE;
9800 (define_expand "negxf2"
9801   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9802         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9803   "TARGET_80387"
9804   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9806 (define_expand "absxf2"
9807   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9808         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9809   "TARGET_80387"
9810   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9812 (define_insn "*absnegxf2_i387"
9813   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9814         (match_operator:XF 3 "absneg_operator"
9815           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9816    (use (match_operand 2 "" ""))
9817    (clobber (reg:CC FLAGS_REG))]
9818   "TARGET_80387
9819    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9820   "#")
9822 ;; Splitters for fp abs and neg.
9824 (define_split
9825   [(set (match_operand 0 "fp_register_operand" "")
9826         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9827    (use (match_operand 2 "" ""))
9828    (clobber (reg:CC FLAGS_REG))]
9829   "reload_completed"
9830   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9832 (define_split
9833   [(set (match_operand 0 "register_operand" "")
9834         (match_operator 3 "absneg_operator"
9835           [(match_operand 1 "register_operand" "")]))
9836    (use (match_operand 2 "nonimmediate_operand" ""))
9837    (clobber (reg:CC FLAGS_REG))]
9838   "reload_completed && SSE_REG_P (operands[0])"
9839   [(set (match_dup 0) (match_dup 3))]
9841   enum machine_mode mode = GET_MODE (operands[0]);
9842   enum machine_mode vmode = GET_MODE (operands[2]);
9843   rtx tmp;
9845   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9846   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9847   if (operands_match_p (operands[0], operands[2]))
9848     {
9849       tmp = operands[1];
9850       operands[1] = operands[2];
9851       operands[2] = tmp;
9852     }
9853   if (GET_CODE (operands[3]) == ABS)
9854     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9855   else
9856     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9857   operands[3] = tmp;
9860 (define_split
9861   [(set (match_operand:SF 0 "register_operand" "")
9862         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9863    (use (match_operand:V4SF 2 "" ""))
9864    (clobber (reg:CC FLAGS_REG))]
9865   "reload_completed"
9866   [(parallel [(set (match_dup 0) (match_dup 1))
9867               (clobber (reg:CC FLAGS_REG))])]
9869   rtx tmp;
9870   operands[0] = gen_lowpart (SImode, operands[0]);
9871   if (GET_CODE (operands[1]) == ABS)
9872     {
9873       tmp = gen_int_mode (0x7fffffff, SImode);
9874       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9875     }
9876   else
9877     {
9878       tmp = gen_int_mode (0x80000000, SImode);
9879       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9880     }
9881   operands[1] = tmp;
9884 (define_split
9885   [(set (match_operand:DF 0 "register_operand" "")
9886         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9887    (use (match_operand 2 "" ""))
9888    (clobber (reg:CC FLAGS_REG))]
9889   "reload_completed"
9890   [(parallel [(set (match_dup 0) (match_dup 1))
9891               (clobber (reg:CC FLAGS_REG))])]
9893   rtx tmp;
9894   if (TARGET_64BIT)
9895     {
9896       tmp = gen_lowpart (DImode, operands[0]);
9897       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9898       operands[0] = tmp;
9900       if (GET_CODE (operands[1]) == ABS)
9901         tmp = const0_rtx;
9902       else
9903         tmp = gen_rtx_NOT (DImode, tmp);
9904     }
9905   else
9906     {
9907       operands[0] = gen_highpart (SImode, operands[0]);
9908       if (GET_CODE (operands[1]) == ABS)
9909         {
9910           tmp = gen_int_mode (0x7fffffff, SImode);
9911           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9912         }
9913       else
9914         {
9915           tmp = gen_int_mode (0x80000000, SImode);
9916           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9917         }
9918     }
9919   operands[1] = tmp;
9922 (define_split
9923   [(set (match_operand:XF 0 "register_operand" "")
9924         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9925    (use (match_operand 2 "" ""))
9926    (clobber (reg:CC FLAGS_REG))]
9927   "reload_completed"
9928   [(parallel [(set (match_dup 0) (match_dup 1))
9929               (clobber (reg:CC FLAGS_REG))])]
9931   rtx tmp;
9932   operands[0] = gen_rtx_REG (SImode,
9933                              true_regnum (operands[0])
9934                              + (TARGET_64BIT ? 1 : 2));
9935   if (GET_CODE (operands[1]) == ABS)
9936     {
9937       tmp = GEN_INT (0x7fff);
9938       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9939     }
9940   else
9941     {
9942       tmp = GEN_INT (0x8000);
9943       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9944     }
9945   operands[1] = tmp;
9948 (define_split
9949   [(set (match_operand 0 "memory_operand" "")
9950         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9951    (use (match_operand 2 "" ""))
9952    (clobber (reg:CC FLAGS_REG))]
9953   "reload_completed"
9954   [(parallel [(set (match_dup 0) (match_dup 1))
9955               (clobber (reg:CC FLAGS_REG))])]
9957   enum machine_mode mode = GET_MODE (operands[0]);
9958   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9959   rtx tmp;
9961   operands[0] = adjust_address (operands[0], QImode, size - 1);
9962   if (GET_CODE (operands[1]) == ABS)
9963     {
9964       tmp = gen_int_mode (0x7f, QImode);
9965       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9966     }
9967   else
9968     {
9969       tmp = gen_int_mode (0x80, QImode);
9970       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9971     }
9972   operands[1] = tmp;
9975 ;; Conditionalize these after reload. If they match before reload, we
9976 ;; lose the clobber and ability to use integer instructions.
9978 (define_insn "*negsf2_1"
9979   [(set (match_operand:SF 0 "register_operand" "=f")
9980         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9981   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9982   "fchs"
9983   [(set_attr "type" "fsgn")
9984    (set_attr "mode" "SF")])
9986 (define_insn "*negdf2_1"
9987   [(set (match_operand:DF 0 "register_operand" "=f")
9988         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9989   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9990   "fchs"
9991   [(set_attr "type" "fsgn")
9992    (set_attr "mode" "DF")])
9994 (define_insn "*negxf2_1"
9995   [(set (match_operand:XF 0 "register_operand" "=f")
9996         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9997   "TARGET_80387"
9998   "fchs"
9999   [(set_attr "type" "fsgn")
10000    (set_attr "mode" "XF")])
10002 (define_insn "*abssf2_1"
10003   [(set (match_operand:SF 0 "register_operand" "=f")
10004         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10005   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10006   "fabs"
10007   [(set_attr "type" "fsgn")
10008    (set_attr "mode" "SF")])
10010 (define_insn "*absdf2_1"
10011   [(set (match_operand:DF 0 "register_operand" "=f")
10012         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10013   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10014   "fabs"
10015   [(set_attr "type" "fsgn")
10016    (set_attr "mode" "DF")])
10018 (define_insn "*absxf2_1"
10019   [(set (match_operand:XF 0 "register_operand" "=f")
10020         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10021   "TARGET_80387"
10022   "fabs"
10023   [(set_attr "type" "fsgn")
10024    (set_attr "mode" "DF")])
10026 (define_insn "*negextendsfdf2"
10027   [(set (match_operand:DF 0 "register_operand" "=f")
10028         (neg:DF (float_extend:DF
10029                   (match_operand:SF 1 "register_operand" "0"))))]
10030   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10031   "fchs"
10032   [(set_attr "type" "fsgn")
10033    (set_attr "mode" "DF")])
10035 (define_insn "*negextenddfxf2"
10036   [(set (match_operand:XF 0 "register_operand" "=f")
10037         (neg:XF (float_extend:XF
10038                   (match_operand:DF 1 "register_operand" "0"))))]
10039   "TARGET_80387"
10040   "fchs"
10041   [(set_attr "type" "fsgn")
10042    (set_attr "mode" "XF")])
10044 (define_insn "*negextendsfxf2"
10045   [(set (match_operand:XF 0 "register_operand" "=f")
10046         (neg:XF (float_extend:XF
10047                   (match_operand:SF 1 "register_operand" "0"))))]
10048   "TARGET_80387"
10049   "fchs"
10050   [(set_attr "type" "fsgn")
10051    (set_attr "mode" "XF")])
10053 (define_insn "*absextendsfdf2"
10054   [(set (match_operand:DF 0 "register_operand" "=f")
10055         (abs:DF (float_extend:DF
10056                   (match_operand:SF 1 "register_operand" "0"))))]
10057   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10058   "fabs"
10059   [(set_attr "type" "fsgn")
10060    (set_attr "mode" "DF")])
10062 (define_insn "*absextenddfxf2"
10063   [(set (match_operand:XF 0 "register_operand" "=f")
10064         (abs:XF (float_extend:XF
10065           (match_operand:DF 1 "register_operand" "0"))))]
10066   "TARGET_80387"
10067   "fabs"
10068   [(set_attr "type" "fsgn")
10069    (set_attr "mode" "XF")])
10071 (define_insn "*absextendsfxf2"
10072   [(set (match_operand:XF 0 "register_operand" "=f")
10073         (abs:XF (float_extend:XF
10074           (match_operand:SF 1 "register_operand" "0"))))]
10075   "TARGET_80387"
10076   "fabs"
10077   [(set_attr "type" "fsgn")
10078    (set_attr "mode" "XF")])
10080 ;; One complement instructions
10082 (define_expand "one_cmpldi2"
10083   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10084         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10085   "TARGET_64BIT"
10086   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10088 (define_insn "*one_cmpldi2_1_rex64"
10089   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10090         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10091   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10092   "not{q}\t%0"
10093   [(set_attr "type" "negnot")
10094    (set_attr "mode" "DI")])
10096 (define_insn "*one_cmpldi2_2_rex64"
10097   [(set (reg FLAGS_REG)
10098         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10099                  (const_int 0)))
10100    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10101         (not:DI (match_dup 1)))]
10102   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10103    && ix86_unary_operator_ok (NOT, DImode, operands)"
10104   "#"
10105   [(set_attr "type" "alu1")
10106    (set_attr "mode" "DI")])
10108 (define_split
10109   [(set (match_operand 0 "flags_reg_operand" "")
10110         (match_operator 2 "compare_operator"
10111           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10112            (const_int 0)]))
10113    (set (match_operand:DI 1 "nonimmediate_operand" "")
10114         (not:DI (match_dup 3)))]
10115   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10116   [(parallel [(set (match_dup 0)
10117                    (match_op_dup 2
10118                      [(xor:DI (match_dup 3) (const_int -1))
10119                       (const_int 0)]))
10120               (set (match_dup 1)
10121                    (xor:DI (match_dup 3) (const_int -1)))])]
10122   "")
10124 (define_expand "one_cmplsi2"
10125   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10126         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10127   ""
10128   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10130 (define_insn "*one_cmplsi2_1"
10131   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10132         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10133   "ix86_unary_operator_ok (NOT, SImode, operands)"
10134   "not{l}\t%0"
10135   [(set_attr "type" "negnot")
10136    (set_attr "mode" "SI")])
10138 ;; ??? Currently never generated - xor is used instead.
10139 (define_insn "*one_cmplsi2_1_zext"
10140   [(set (match_operand:DI 0 "register_operand" "=r")
10141         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10142   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10143   "not{l}\t%k0"
10144   [(set_attr "type" "negnot")
10145    (set_attr "mode" "SI")])
10147 (define_insn "*one_cmplsi2_2"
10148   [(set (reg FLAGS_REG)
10149         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10150                  (const_int 0)))
10151    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10152         (not:SI (match_dup 1)))]
10153   "ix86_match_ccmode (insn, CCNOmode)
10154    && ix86_unary_operator_ok (NOT, SImode, operands)"
10155   "#"
10156   [(set_attr "type" "alu1")
10157    (set_attr "mode" "SI")])
10159 (define_split
10160   [(set (match_operand 0 "flags_reg_operand" "")
10161         (match_operator 2 "compare_operator"
10162           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10163            (const_int 0)]))
10164    (set (match_operand:SI 1 "nonimmediate_operand" "")
10165         (not:SI (match_dup 3)))]
10166   "ix86_match_ccmode (insn, CCNOmode)"
10167   [(parallel [(set (match_dup 0)
10168                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10169                                     (const_int 0)]))
10170               (set (match_dup 1)
10171                    (xor:SI (match_dup 3) (const_int -1)))])]
10172   "")
10174 ;; ??? Currently never generated - xor is used instead.
10175 (define_insn "*one_cmplsi2_2_zext"
10176   [(set (reg FLAGS_REG)
10177         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10178                  (const_int 0)))
10179    (set (match_operand:DI 0 "register_operand" "=r")
10180         (zero_extend:DI (not:SI (match_dup 1))))]
10181   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10182    && ix86_unary_operator_ok (NOT, SImode, operands)"
10183   "#"
10184   [(set_attr "type" "alu1")
10185    (set_attr "mode" "SI")])
10187 (define_split
10188   [(set (match_operand 0 "flags_reg_operand" "")
10189         (match_operator 2 "compare_operator"
10190           [(not:SI (match_operand:SI 3 "register_operand" ""))
10191            (const_int 0)]))
10192    (set (match_operand:DI 1 "register_operand" "")
10193         (zero_extend:DI (not:SI (match_dup 3))))]
10194   "ix86_match_ccmode (insn, CCNOmode)"
10195   [(parallel [(set (match_dup 0)
10196                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10197                                     (const_int 0)]))
10198               (set (match_dup 1)
10199                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10200   "")
10202 (define_expand "one_cmplhi2"
10203   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10204         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10205   "TARGET_HIMODE_MATH"
10206   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10208 (define_insn "*one_cmplhi2_1"
10209   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10210         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10211   "ix86_unary_operator_ok (NOT, HImode, operands)"
10212   "not{w}\t%0"
10213   [(set_attr "type" "negnot")
10214    (set_attr "mode" "HI")])
10216 (define_insn "*one_cmplhi2_2"
10217   [(set (reg FLAGS_REG)
10218         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10219                  (const_int 0)))
10220    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10221         (not:HI (match_dup 1)))]
10222   "ix86_match_ccmode (insn, CCNOmode)
10223    && ix86_unary_operator_ok (NEG, HImode, operands)"
10224   "#"
10225   [(set_attr "type" "alu1")
10226    (set_attr "mode" "HI")])
10228 (define_split
10229   [(set (match_operand 0 "flags_reg_operand" "")
10230         (match_operator 2 "compare_operator"
10231           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10232            (const_int 0)]))
10233    (set (match_operand:HI 1 "nonimmediate_operand" "")
10234         (not:HI (match_dup 3)))]
10235   "ix86_match_ccmode (insn, CCNOmode)"
10236   [(parallel [(set (match_dup 0)
10237                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10238                                     (const_int 0)]))
10239               (set (match_dup 1)
10240                    (xor:HI (match_dup 3) (const_int -1)))])]
10241   "")
10243 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10244 (define_expand "one_cmplqi2"
10245   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10246         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10247   "TARGET_QIMODE_MATH"
10248   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10250 (define_insn "*one_cmplqi2_1"
10251   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10252         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10253   "ix86_unary_operator_ok (NOT, QImode, operands)"
10254   "@
10255    not{b}\t%0
10256    not{l}\t%k0"
10257   [(set_attr "type" "negnot")
10258    (set_attr "mode" "QI,SI")])
10260 (define_insn "*one_cmplqi2_2"
10261   [(set (reg FLAGS_REG)
10262         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10263                  (const_int 0)))
10264    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10265         (not:QI (match_dup 1)))]
10266   "ix86_match_ccmode (insn, CCNOmode)
10267    && ix86_unary_operator_ok (NOT, QImode, operands)"
10268   "#"
10269   [(set_attr "type" "alu1")
10270    (set_attr "mode" "QI")])
10272 (define_split
10273   [(set (match_operand 0 "flags_reg_operand" "")
10274         (match_operator 2 "compare_operator"
10275           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10276            (const_int 0)]))
10277    (set (match_operand:QI 1 "nonimmediate_operand" "")
10278         (not:QI (match_dup 3)))]
10279   "ix86_match_ccmode (insn, CCNOmode)"
10280   [(parallel [(set (match_dup 0)
10281                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10282                                     (const_int 0)]))
10283               (set (match_dup 1)
10284                    (xor:QI (match_dup 3) (const_int -1)))])]
10285   "")
10287 ;; Arithmetic shift instructions
10289 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10290 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10291 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10292 ;; from the assembler input.
10294 ;; This instruction shifts the target reg/mem as usual, but instead of
10295 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10296 ;; is a left shift double, bits are taken from the high order bits of
10297 ;; reg, else if the insn is a shift right double, bits are taken from the
10298 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10299 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10301 ;; Since sh[lr]d does not change the `reg' operand, that is done
10302 ;; separately, making all shifts emit pairs of shift double and normal
10303 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10304 ;; support a 63 bit shift, each shift where the count is in a reg expands
10305 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10307 ;; If the shift count is a constant, we need never emit more than one
10308 ;; shift pair, instead using moves and sign extension for counts greater
10309 ;; than 31.
10311 (define_expand "ashlti3"
10312   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10313                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10314                               (match_operand:QI 2 "nonmemory_operand" "")))
10315               (clobber (reg:CC FLAGS_REG))])]
10316   "TARGET_64BIT"
10318   if (! immediate_operand (operands[2], QImode))
10319     {
10320       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10321       DONE;
10322     }
10323   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10324   DONE;
10327 (define_insn "ashlti3_1"
10328   [(set (match_operand:TI 0 "register_operand" "=r")
10329         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10330                    (match_operand:QI 2 "register_operand" "c")))
10331    (clobber (match_scratch:DI 3 "=&r"))
10332    (clobber (reg:CC FLAGS_REG))]
10333   "TARGET_64BIT"
10334   "#"
10335   [(set_attr "type" "multi")])
10337 (define_insn "*ashlti3_2"
10338   [(set (match_operand:TI 0 "register_operand" "=r")
10339         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10340                    (match_operand:QI 2 "immediate_operand" "O")))
10341    (clobber (reg:CC FLAGS_REG))]
10342   "TARGET_64BIT"
10343   "#"
10344   [(set_attr "type" "multi")])
10346 (define_split
10347   [(set (match_operand:TI 0 "register_operand" "")
10348         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10349                    (match_operand:QI 2 "register_operand" "")))
10350    (clobber (match_scratch:DI 3 ""))
10351    (clobber (reg:CC FLAGS_REG))]
10352   "TARGET_64BIT && reload_completed"
10353   [(const_int 0)]
10354   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10356 (define_split
10357   [(set (match_operand:TI 0 "register_operand" "")
10358         (ashift:TI (match_operand:TI 1 "register_operand" "")
10359                    (match_operand:QI 2 "immediate_operand" "")))
10360    (clobber (reg:CC FLAGS_REG))]
10361   "TARGET_64BIT && reload_completed"
10362   [(const_int 0)]
10363   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10365 (define_insn "x86_64_shld"
10366   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10367         (ior:DI (ashift:DI (match_dup 0)
10368                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10369                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10370                   (minus:QI (const_int 64) (match_dup 2)))))
10371    (clobber (reg:CC FLAGS_REG))]
10372   "TARGET_64BIT"
10373   "@
10374    shld{q}\t{%2, %1, %0|%0, %1, %2}
10375    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10376   [(set_attr "type" "ishift")
10377    (set_attr "prefix_0f" "1")
10378    (set_attr "mode" "DI")
10379    (set_attr "athlon_decode" "vector")
10380    (set_attr "amdfam10_decode" "vector")])   
10382 (define_expand "x86_64_shift_adj"
10383   [(set (reg:CCZ FLAGS_REG)
10384         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10385                              (const_int 64))
10386                      (const_int 0)))
10387    (set (match_operand:DI 0 "register_operand" "")
10388         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10389                          (match_operand:DI 1 "register_operand" "")
10390                          (match_dup 0)))
10391    (set (match_dup 1)
10392         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10393                          (match_operand:DI 3 "register_operand" "r")
10394                          (match_dup 1)))]
10395   "TARGET_64BIT"
10396   "")
10398 (define_expand "ashldi3"
10399   [(set (match_operand:DI 0 "shiftdi_operand" "")
10400         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10401                    (match_operand:QI 2 "nonmemory_operand" "")))]
10402   ""
10403   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10405 (define_insn "*ashldi3_1_rex64"
10406   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10407         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10408                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10409    (clobber (reg:CC FLAGS_REG))]
10410   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10412   switch (get_attr_type (insn))
10413     {
10414     case TYPE_ALU:
10415       gcc_assert (operands[2] == const1_rtx);
10416       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10417       return "add{q}\t%0, %0";
10419     case TYPE_LEA:
10420       gcc_assert (CONST_INT_P (operands[2]));
10421       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10422       operands[1] = gen_rtx_MULT (DImode, operands[1],
10423                                   GEN_INT (1 << INTVAL (operands[2])));
10424       return "lea{q}\t{%a1, %0|%0, %a1}";
10426     default:
10427       if (REG_P (operands[2]))
10428         return "sal{q}\t{%b2, %0|%0, %b2}";
10429       else if (operands[2] == const1_rtx
10430                && (TARGET_SHIFT1 || optimize_size))
10431         return "sal{q}\t%0";
10432       else
10433         return "sal{q}\t{%2, %0|%0, %2}";
10434     }
10436   [(set (attr "type")
10437      (cond [(eq_attr "alternative" "1")
10438               (const_string "lea")
10439             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10440                           (const_int 0))
10441                       (match_operand 0 "register_operand" ""))
10442                  (match_operand 2 "const1_operand" ""))
10443               (const_string "alu")
10444            ]
10445            (const_string "ishift")))
10446    (set_attr "mode" "DI")])
10448 ;; Convert lea to the lea pattern to avoid flags dependency.
10449 (define_split
10450   [(set (match_operand:DI 0 "register_operand" "")
10451         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10452                    (match_operand:QI 2 "immediate_operand" "")))
10453    (clobber (reg:CC FLAGS_REG))]
10454   "TARGET_64BIT && reload_completed
10455    && true_regnum (operands[0]) != true_regnum (operands[1])"
10456   [(set (match_dup 0)
10457         (mult:DI (match_dup 1)
10458                  (match_dup 2)))]
10459   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10461 ;; This pattern can't accept a variable shift count, since shifts by
10462 ;; zero don't affect the flags.  We assume that shifts by constant
10463 ;; zero are optimized away.
10464 (define_insn "*ashldi3_cmp_rex64"
10465   [(set (reg FLAGS_REG)
10466         (compare
10467           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10468                      (match_operand:QI 2 "immediate_operand" "e"))
10469           (const_int 0)))
10470    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10471         (ashift:DI (match_dup 1) (match_dup 2)))]
10472   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10473    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10474    && (optimize_size
10475        || !TARGET_PARTIAL_FLAG_REG_STALL
10476        || (operands[2] == const1_rtx
10477            && (TARGET_SHIFT1
10478                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10480   switch (get_attr_type (insn))
10481     {
10482     case TYPE_ALU:
10483       gcc_assert (operands[2] == const1_rtx);
10484       return "add{q}\t%0, %0";
10486     default:
10487       if (REG_P (operands[2]))
10488         return "sal{q}\t{%b2, %0|%0, %b2}";
10489       else if (operands[2] == const1_rtx
10490                && (TARGET_SHIFT1 || optimize_size))
10491         return "sal{q}\t%0";
10492       else
10493         return "sal{q}\t{%2, %0|%0, %2}";
10494     }
10496   [(set (attr "type")
10497      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10498                           (const_int 0))
10499                       (match_operand 0 "register_operand" ""))
10500                  (match_operand 2 "const1_operand" ""))
10501               (const_string "alu")
10502            ]
10503            (const_string "ishift")))
10504    (set_attr "mode" "DI")])
10506 (define_insn "*ashldi3_cconly_rex64"
10507   [(set (reg FLAGS_REG)
10508         (compare
10509           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10510                      (match_operand:QI 2 "immediate_operand" "e"))
10511           (const_int 0)))
10512    (clobber (match_scratch:DI 0 "=r"))]
10513   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10514    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10515    && (optimize_size
10516        || !TARGET_PARTIAL_FLAG_REG_STALL
10517        || (operands[2] == const1_rtx
10518            && (TARGET_SHIFT1
10519                || TARGET_DOUBLE_WITH_ADD)))"
10521   switch (get_attr_type (insn))
10522     {
10523     case TYPE_ALU:
10524       gcc_assert (operands[2] == const1_rtx);
10525       return "add{q}\t%0, %0";
10527     default:
10528       if (REG_P (operands[2]))
10529         return "sal{q}\t{%b2, %0|%0, %b2}";
10530       else if (operands[2] == const1_rtx
10531                && (TARGET_SHIFT1 || optimize_size))
10532         return "sal{q}\t%0";
10533       else
10534         return "sal{q}\t{%2, %0|%0, %2}";
10535     }
10537   [(set (attr "type")
10538      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10539                           (const_int 0))
10540                       (match_operand 0 "register_operand" ""))
10541                  (match_operand 2 "const1_operand" ""))
10542               (const_string "alu")
10543            ]
10544            (const_string "ishift")))
10545    (set_attr "mode" "DI")])
10547 (define_insn "*ashldi3_1"
10548   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10549         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10550                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10551    (clobber (reg:CC FLAGS_REG))]
10552   "!TARGET_64BIT"
10553   "#"
10554   [(set_attr "type" "multi")])
10556 ;; By default we don't ask for a scratch register, because when DImode
10557 ;; values are manipulated, registers are already at a premium.  But if
10558 ;; we have one handy, we won't turn it away.
10559 (define_peephole2
10560   [(match_scratch:SI 3 "r")
10561    (parallel [(set (match_operand:DI 0 "register_operand" "")
10562                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10563                               (match_operand:QI 2 "nonmemory_operand" "")))
10564               (clobber (reg:CC FLAGS_REG))])
10565    (match_dup 3)]
10566   "!TARGET_64BIT && TARGET_CMOVE"
10567   [(const_int 0)]
10568   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10570 (define_split
10571   [(set (match_operand:DI 0 "register_operand" "")
10572         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10573                    (match_operand:QI 2 "nonmemory_operand" "")))
10574    (clobber (reg:CC FLAGS_REG))]
10575   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10576                      ? flow2_completed : reload_completed)"
10577   [(const_int 0)]
10578   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10580 (define_insn "x86_shld_1"
10581   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10582         (ior:SI (ashift:SI (match_dup 0)
10583                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10584                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10585                   (minus:QI (const_int 32) (match_dup 2)))))
10586    (clobber (reg:CC FLAGS_REG))]
10587   ""
10588   "@
10589    shld{l}\t{%2, %1, %0|%0, %1, %2}
10590    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10591   [(set_attr "type" "ishift")
10592    (set_attr "prefix_0f" "1")
10593    (set_attr "mode" "SI")
10594    (set_attr "pent_pair" "np")
10595    (set_attr "athlon_decode" "vector")
10596    (set_attr "amdfam10_decode" "vector")])   
10598 (define_expand "x86_shift_adj_1"
10599   [(set (reg:CCZ FLAGS_REG)
10600         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10601                              (const_int 32))
10602                      (const_int 0)))
10603    (set (match_operand:SI 0 "register_operand" "")
10604         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10605                          (match_operand:SI 1 "register_operand" "")
10606                          (match_dup 0)))
10607    (set (match_dup 1)
10608         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10609                          (match_operand:SI 3 "register_operand" "r")
10610                          (match_dup 1)))]
10611   "TARGET_CMOVE"
10612   "")
10614 (define_expand "x86_shift_adj_2"
10615   [(use (match_operand:SI 0 "register_operand" ""))
10616    (use (match_operand:SI 1 "register_operand" ""))
10617    (use (match_operand:QI 2 "register_operand" ""))]
10618   ""
10620   rtx label = gen_label_rtx ();
10621   rtx tmp;
10623   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10625   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10626   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10627   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10628                               gen_rtx_LABEL_REF (VOIDmode, label),
10629                               pc_rtx);
10630   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10631   JUMP_LABEL (tmp) = label;
10633   emit_move_insn (operands[0], operands[1]);
10634   ix86_expand_clear (operands[1]);
10636   emit_label (label);
10637   LABEL_NUSES (label) = 1;
10639   DONE;
10642 (define_expand "ashlsi3"
10643   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10644         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10645                    (match_operand:QI 2 "nonmemory_operand" "")))
10646    (clobber (reg:CC FLAGS_REG))]
10647   ""
10648   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10650 (define_insn "*ashlsi3_1"
10651   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10652         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10653                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10654    (clobber (reg:CC FLAGS_REG))]
10655   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10657   switch (get_attr_type (insn))
10658     {
10659     case TYPE_ALU:
10660       gcc_assert (operands[2] == const1_rtx);
10661       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10662       return "add{l}\t%0, %0";
10664     case TYPE_LEA:
10665       return "#";
10667     default:
10668       if (REG_P (operands[2]))
10669         return "sal{l}\t{%b2, %0|%0, %b2}";
10670       else if (operands[2] == const1_rtx
10671                && (TARGET_SHIFT1 || optimize_size))
10672         return "sal{l}\t%0";
10673       else
10674         return "sal{l}\t{%2, %0|%0, %2}";
10675     }
10677   [(set (attr "type")
10678      (cond [(eq_attr "alternative" "1")
10679               (const_string "lea")
10680             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10681                           (const_int 0))
10682                       (match_operand 0 "register_operand" ""))
10683                  (match_operand 2 "const1_operand" ""))
10684               (const_string "alu")
10685            ]
10686            (const_string "ishift")))
10687    (set_attr "mode" "SI")])
10689 ;; Convert lea to the lea pattern to avoid flags dependency.
10690 (define_split
10691   [(set (match_operand 0 "register_operand" "")
10692         (ashift (match_operand 1 "index_register_operand" "")
10693                 (match_operand:QI 2 "const_int_operand" "")))
10694    (clobber (reg:CC FLAGS_REG))]
10695   "reload_completed
10696    && true_regnum (operands[0]) != true_regnum (operands[1])
10697    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10698   [(const_int 0)]
10700   rtx pat;
10701   enum machine_mode mode = GET_MODE (operands[0]);
10703   if (GET_MODE_SIZE (mode) < 4)
10704     operands[0] = gen_lowpart (SImode, operands[0]);
10705   if (mode != Pmode)
10706     operands[1] = gen_lowpart (Pmode, operands[1]);
10707   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10709   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10710   if (Pmode != SImode)
10711     pat = gen_rtx_SUBREG (SImode, pat, 0);
10712   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10713   DONE;
10716 ;; Rare case of shifting RSP is handled by generating move and shift
10717 (define_split
10718   [(set (match_operand 0 "register_operand" "")
10719         (ashift (match_operand 1 "register_operand" "")
10720                 (match_operand:QI 2 "const_int_operand" "")))
10721    (clobber (reg:CC FLAGS_REG))]
10722   "reload_completed
10723    && true_regnum (operands[0]) != true_regnum (operands[1])"
10724   [(const_int 0)]
10726   rtx pat, clob;
10727   emit_move_insn (operands[0], operands[1]);
10728   pat = gen_rtx_SET (VOIDmode, operands[0],
10729                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10730                                      operands[0], operands[2]));
10731   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10732   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10733   DONE;
10736 (define_insn "*ashlsi3_1_zext"
10737   [(set (match_operand:DI 0 "register_operand" "=r,r")
10738         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10739                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10740    (clobber (reg:CC FLAGS_REG))]
10741   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10743   switch (get_attr_type (insn))
10744     {
10745     case TYPE_ALU:
10746       gcc_assert (operands[2] == const1_rtx);
10747       return "add{l}\t%k0, %k0";
10749     case TYPE_LEA:
10750       return "#";
10752     default:
10753       if (REG_P (operands[2]))
10754         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10755       else if (operands[2] == const1_rtx
10756                && (TARGET_SHIFT1 || optimize_size))
10757         return "sal{l}\t%k0";
10758       else
10759         return "sal{l}\t{%2, %k0|%k0, %2}";
10760     }
10762   [(set (attr "type")
10763      (cond [(eq_attr "alternative" "1")
10764               (const_string "lea")
10765             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10766                      (const_int 0))
10767                  (match_operand 2 "const1_operand" ""))
10768               (const_string "alu")
10769            ]
10770            (const_string "ishift")))
10771    (set_attr "mode" "SI")])
10773 ;; Convert lea to the lea pattern to avoid flags dependency.
10774 (define_split
10775   [(set (match_operand:DI 0 "register_operand" "")
10776         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10777                                 (match_operand:QI 2 "const_int_operand" ""))))
10778    (clobber (reg:CC FLAGS_REG))]
10779   "TARGET_64BIT && reload_completed
10780    && true_regnum (operands[0]) != true_regnum (operands[1])"
10781   [(set (match_dup 0) (zero_extend:DI
10782                         (subreg:SI (mult:SI (match_dup 1)
10783                                             (match_dup 2)) 0)))]
10785   operands[1] = gen_lowpart (Pmode, operands[1]);
10786   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10789 ;; This pattern can't accept a variable shift count, since shifts by
10790 ;; zero don't affect the flags.  We assume that shifts by constant
10791 ;; zero are optimized away.
10792 (define_insn "*ashlsi3_cmp"
10793   [(set (reg FLAGS_REG)
10794         (compare
10795           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10796                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10797           (const_int 0)))
10798    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10799         (ashift:SI (match_dup 1) (match_dup 2)))]
10800   "ix86_match_ccmode (insn, CCGOCmode)
10801    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10802    && (optimize_size
10803        || !TARGET_PARTIAL_FLAG_REG_STALL
10804        || (operands[2] == const1_rtx
10805            && (TARGET_SHIFT1
10806                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10808   switch (get_attr_type (insn))
10809     {
10810     case TYPE_ALU:
10811       gcc_assert (operands[2] == const1_rtx);
10812       return "add{l}\t%0, %0";
10814     default:
10815       if (REG_P (operands[2]))
10816         return "sal{l}\t{%b2, %0|%0, %b2}";
10817       else if (operands[2] == const1_rtx
10818                && (TARGET_SHIFT1 || optimize_size))
10819         return "sal{l}\t%0";
10820       else
10821         return "sal{l}\t{%2, %0|%0, %2}";
10822     }
10824   [(set (attr "type")
10825      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10826                           (const_int 0))
10827                       (match_operand 0 "register_operand" ""))
10828                  (match_operand 2 "const1_operand" ""))
10829               (const_string "alu")
10830            ]
10831            (const_string "ishift")))
10832    (set_attr "mode" "SI")])
10834 (define_insn "*ashlsi3_cconly"
10835   [(set (reg FLAGS_REG)
10836         (compare
10837           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10838                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10839           (const_int 0)))
10840    (clobber (match_scratch:SI 0 "=r"))]
10841   "ix86_match_ccmode (insn, CCGOCmode)
10842    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10843    && (optimize_size
10844        || !TARGET_PARTIAL_FLAG_REG_STALL
10845        || (operands[2] == const1_rtx
10846            && (TARGET_SHIFT1
10847                || TARGET_DOUBLE_WITH_ADD)))"
10849   switch (get_attr_type (insn))
10850     {
10851     case TYPE_ALU:
10852       gcc_assert (operands[2] == const1_rtx);
10853       return "add{l}\t%0, %0";
10855     default:
10856       if (REG_P (operands[2]))
10857         return "sal{l}\t{%b2, %0|%0, %b2}";
10858       else if (operands[2] == const1_rtx
10859                && (TARGET_SHIFT1 || optimize_size))
10860         return "sal{l}\t%0";
10861       else
10862         return "sal{l}\t{%2, %0|%0, %2}";
10863     }
10865   [(set (attr "type")
10866      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10867                           (const_int 0))
10868                       (match_operand 0 "register_operand" ""))
10869                  (match_operand 2 "const1_operand" ""))
10870               (const_string "alu")
10871            ]
10872            (const_string "ishift")))
10873    (set_attr "mode" "SI")])
10875 (define_insn "*ashlsi3_cmp_zext"
10876   [(set (reg FLAGS_REG)
10877         (compare
10878           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10879                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10880           (const_int 0)))
10881    (set (match_operand:DI 0 "register_operand" "=r")
10882         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10883   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10884    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10885    && (optimize_size
10886        || !TARGET_PARTIAL_FLAG_REG_STALL
10887        || (operands[2] == const1_rtx
10888            && (TARGET_SHIFT1
10889                || TARGET_DOUBLE_WITH_ADD)))"
10891   switch (get_attr_type (insn))
10892     {
10893     case TYPE_ALU:
10894       gcc_assert (operands[2] == const1_rtx);
10895       return "add{l}\t%k0, %k0";
10897     default:
10898       if (REG_P (operands[2]))
10899         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10900       else if (operands[2] == const1_rtx
10901                && (TARGET_SHIFT1 || optimize_size))
10902         return "sal{l}\t%k0";
10903       else
10904         return "sal{l}\t{%2, %k0|%k0, %2}";
10905     }
10907   [(set (attr "type")
10908      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10909                      (const_int 0))
10910                  (match_operand 2 "const1_operand" ""))
10911               (const_string "alu")
10912            ]
10913            (const_string "ishift")))
10914    (set_attr "mode" "SI")])
10916 (define_expand "ashlhi3"
10917   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10918         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10919                    (match_operand:QI 2 "nonmemory_operand" "")))
10920    (clobber (reg:CC FLAGS_REG))]
10921   "TARGET_HIMODE_MATH"
10922   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10924 (define_insn "*ashlhi3_1_lea"
10925   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10926         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10927                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10928    (clobber (reg:CC FLAGS_REG))]
10929   "!TARGET_PARTIAL_REG_STALL
10930    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10932   switch (get_attr_type (insn))
10933     {
10934     case TYPE_LEA:
10935       return "#";
10936     case TYPE_ALU:
10937       gcc_assert (operands[2] == const1_rtx);
10938       return "add{w}\t%0, %0";
10940     default:
10941       if (REG_P (operands[2]))
10942         return "sal{w}\t{%b2, %0|%0, %b2}";
10943       else if (operands[2] == const1_rtx
10944                && (TARGET_SHIFT1 || optimize_size))
10945         return "sal{w}\t%0";
10946       else
10947         return "sal{w}\t{%2, %0|%0, %2}";
10948     }
10950   [(set (attr "type")
10951      (cond [(eq_attr "alternative" "1")
10952               (const_string "lea")
10953             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10954                           (const_int 0))
10955                       (match_operand 0 "register_operand" ""))
10956                  (match_operand 2 "const1_operand" ""))
10957               (const_string "alu")
10958            ]
10959            (const_string "ishift")))
10960    (set_attr "mode" "HI,SI")])
10962 (define_insn "*ashlhi3_1"
10963   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10964         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10965                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10966    (clobber (reg:CC FLAGS_REG))]
10967   "TARGET_PARTIAL_REG_STALL
10968    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10970   switch (get_attr_type (insn))
10971     {
10972     case TYPE_ALU:
10973       gcc_assert (operands[2] == const1_rtx);
10974       return "add{w}\t%0, %0";
10976     default:
10977       if (REG_P (operands[2]))
10978         return "sal{w}\t{%b2, %0|%0, %b2}";
10979       else if (operands[2] == const1_rtx
10980                && (TARGET_SHIFT1 || optimize_size))
10981         return "sal{w}\t%0";
10982       else
10983         return "sal{w}\t{%2, %0|%0, %2}";
10984     }
10986   [(set (attr "type")
10987      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10988                           (const_int 0))
10989                       (match_operand 0 "register_operand" ""))
10990                  (match_operand 2 "const1_operand" ""))
10991               (const_string "alu")
10992            ]
10993            (const_string "ishift")))
10994    (set_attr "mode" "HI")])
10996 ;; This pattern can't accept a variable shift count, since shifts by
10997 ;; zero don't affect the flags.  We assume that shifts by constant
10998 ;; zero are optimized away.
10999 (define_insn "*ashlhi3_cmp"
11000   [(set (reg FLAGS_REG)
11001         (compare
11002           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11003                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11004           (const_int 0)))
11005    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11006         (ashift:HI (match_dup 1) (match_dup 2)))]
11007   "ix86_match_ccmode (insn, CCGOCmode)
11008    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11009    && (optimize_size
11010        || !TARGET_PARTIAL_FLAG_REG_STALL
11011        || (operands[2] == const1_rtx
11012            && (TARGET_SHIFT1
11013                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11015   switch (get_attr_type (insn))
11016     {
11017     case TYPE_ALU:
11018       gcc_assert (operands[2] == const1_rtx);
11019       return "add{w}\t%0, %0";
11021     default:
11022       if (REG_P (operands[2]))
11023         return "sal{w}\t{%b2, %0|%0, %b2}";
11024       else if (operands[2] == const1_rtx
11025                && (TARGET_SHIFT1 || optimize_size))
11026         return "sal{w}\t%0";
11027       else
11028         return "sal{w}\t{%2, %0|%0, %2}";
11029     }
11031   [(set (attr "type")
11032      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11033                           (const_int 0))
11034                       (match_operand 0 "register_operand" ""))
11035                  (match_operand 2 "const1_operand" ""))
11036               (const_string "alu")
11037            ]
11038            (const_string "ishift")))
11039    (set_attr "mode" "HI")])
11041 (define_insn "*ashlhi3_cconly"
11042   [(set (reg FLAGS_REG)
11043         (compare
11044           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11045                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11046           (const_int 0)))
11047    (clobber (match_scratch:HI 0 "=r"))]
11048   "ix86_match_ccmode (insn, CCGOCmode)
11049    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11050    && (optimize_size
11051        || !TARGET_PARTIAL_FLAG_REG_STALL
11052        || (operands[2] == const1_rtx
11053            && (TARGET_SHIFT1
11054                || TARGET_DOUBLE_WITH_ADD)))"
11056   switch (get_attr_type (insn))
11057     {
11058     case TYPE_ALU:
11059       gcc_assert (operands[2] == const1_rtx);
11060       return "add{w}\t%0, %0";
11062     default:
11063       if (REG_P (operands[2]))
11064         return "sal{w}\t{%b2, %0|%0, %b2}";
11065       else if (operands[2] == const1_rtx
11066                && (TARGET_SHIFT1 || optimize_size))
11067         return "sal{w}\t%0";
11068       else
11069         return "sal{w}\t{%2, %0|%0, %2}";
11070     }
11072   [(set (attr "type")
11073      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11074                           (const_int 0))
11075                       (match_operand 0 "register_operand" ""))
11076                  (match_operand 2 "const1_operand" ""))
11077               (const_string "alu")
11078            ]
11079            (const_string "ishift")))
11080    (set_attr "mode" "HI")])
11082 (define_expand "ashlqi3"
11083   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11084         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11085                    (match_operand:QI 2 "nonmemory_operand" "")))
11086    (clobber (reg:CC FLAGS_REG))]
11087   "TARGET_QIMODE_MATH"
11088   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11090 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11092 (define_insn "*ashlqi3_1_lea"
11093   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11094         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11095                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11096    (clobber (reg:CC FLAGS_REG))]
11097   "!TARGET_PARTIAL_REG_STALL
11098    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11100   switch (get_attr_type (insn))
11101     {
11102     case TYPE_LEA:
11103       return "#";
11104     case TYPE_ALU:
11105       gcc_assert (operands[2] == const1_rtx);
11106       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11107         return "add{l}\t%k0, %k0";
11108       else
11109         return "add{b}\t%0, %0";
11111     default:
11112       if (REG_P (operands[2]))
11113         {
11114           if (get_attr_mode (insn) == MODE_SI)
11115             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11116           else
11117             return "sal{b}\t{%b2, %0|%0, %b2}";
11118         }
11119       else if (operands[2] == const1_rtx
11120                && (TARGET_SHIFT1 || optimize_size))
11121         {
11122           if (get_attr_mode (insn) == MODE_SI)
11123             return "sal{l}\t%0";
11124           else
11125             return "sal{b}\t%0";
11126         }
11127       else
11128         {
11129           if (get_attr_mode (insn) == MODE_SI)
11130             return "sal{l}\t{%2, %k0|%k0, %2}";
11131           else
11132             return "sal{b}\t{%2, %0|%0, %2}";
11133         }
11134     }
11136   [(set (attr "type")
11137      (cond [(eq_attr "alternative" "2")
11138               (const_string "lea")
11139             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11140                           (const_int 0))
11141                       (match_operand 0 "register_operand" ""))
11142                  (match_operand 2 "const1_operand" ""))
11143               (const_string "alu")
11144            ]
11145            (const_string "ishift")))
11146    (set_attr "mode" "QI,SI,SI")])
11148 (define_insn "*ashlqi3_1"
11149   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11150         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11151                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11152    (clobber (reg:CC FLAGS_REG))]
11153   "TARGET_PARTIAL_REG_STALL
11154    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11156   switch (get_attr_type (insn))
11157     {
11158     case TYPE_ALU:
11159       gcc_assert (operands[2] == const1_rtx);
11160       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11161         return "add{l}\t%k0, %k0";
11162       else
11163         return "add{b}\t%0, %0";
11165     default:
11166       if (REG_P (operands[2]))
11167         {
11168           if (get_attr_mode (insn) == MODE_SI)
11169             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11170           else
11171             return "sal{b}\t{%b2, %0|%0, %b2}";
11172         }
11173       else if (operands[2] == const1_rtx
11174                && (TARGET_SHIFT1 || optimize_size))
11175         {
11176           if (get_attr_mode (insn) == MODE_SI)
11177             return "sal{l}\t%0";
11178           else
11179             return "sal{b}\t%0";
11180         }
11181       else
11182         {
11183           if (get_attr_mode (insn) == MODE_SI)
11184             return "sal{l}\t{%2, %k0|%k0, %2}";
11185           else
11186             return "sal{b}\t{%2, %0|%0, %2}";
11187         }
11188     }
11190   [(set (attr "type")
11191      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11192                           (const_int 0))
11193                       (match_operand 0 "register_operand" ""))
11194                  (match_operand 2 "const1_operand" ""))
11195               (const_string "alu")
11196            ]
11197            (const_string "ishift")))
11198    (set_attr "mode" "QI,SI")])
11200 ;; This pattern can't accept a variable shift count, since shifts by
11201 ;; zero don't affect the flags.  We assume that shifts by constant
11202 ;; zero are optimized away.
11203 (define_insn "*ashlqi3_cmp"
11204   [(set (reg FLAGS_REG)
11205         (compare
11206           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11207                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11208           (const_int 0)))
11209    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11210         (ashift:QI (match_dup 1) (match_dup 2)))]
11211   "ix86_match_ccmode (insn, CCGOCmode)
11212    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11213    && (optimize_size
11214        || !TARGET_PARTIAL_FLAG_REG_STALL
11215        || (operands[2] == const1_rtx
11216            && (TARGET_SHIFT1
11217                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11219   switch (get_attr_type (insn))
11220     {
11221     case TYPE_ALU:
11222       gcc_assert (operands[2] == const1_rtx);
11223       return "add{b}\t%0, %0";
11225     default:
11226       if (REG_P (operands[2]))
11227         return "sal{b}\t{%b2, %0|%0, %b2}";
11228       else if (operands[2] == const1_rtx
11229                && (TARGET_SHIFT1 || optimize_size))
11230         return "sal{b}\t%0";
11231       else
11232         return "sal{b}\t{%2, %0|%0, %2}";
11233     }
11235   [(set (attr "type")
11236      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11237                           (const_int 0))
11238                       (match_operand 0 "register_operand" ""))
11239                  (match_operand 2 "const1_operand" ""))
11240               (const_string "alu")
11241            ]
11242            (const_string "ishift")))
11243    (set_attr "mode" "QI")])
11245 (define_insn "*ashlqi3_cconly"
11246   [(set (reg FLAGS_REG)
11247         (compare
11248           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11249                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11250           (const_int 0)))
11251    (clobber (match_scratch:QI 0 "=q"))]
11252   "ix86_match_ccmode (insn, CCGOCmode)
11253    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11254    && (optimize_size
11255        || !TARGET_PARTIAL_FLAG_REG_STALL
11256        || (operands[2] == const1_rtx
11257            && (TARGET_SHIFT1
11258                || TARGET_DOUBLE_WITH_ADD)))"
11260   switch (get_attr_type (insn))
11261     {
11262     case TYPE_ALU:
11263       gcc_assert (operands[2] == const1_rtx);
11264       return "add{b}\t%0, %0";
11266     default:
11267       if (REG_P (operands[2]))
11268         return "sal{b}\t{%b2, %0|%0, %b2}";
11269       else if (operands[2] == const1_rtx
11270                && (TARGET_SHIFT1 || optimize_size))
11271         return "sal{b}\t%0";
11272       else
11273         return "sal{b}\t{%2, %0|%0, %2}";
11274     }
11276   [(set (attr "type")
11277      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11278                           (const_int 0))
11279                       (match_operand 0 "register_operand" ""))
11280                  (match_operand 2 "const1_operand" ""))
11281               (const_string "alu")
11282            ]
11283            (const_string "ishift")))
11284    (set_attr "mode" "QI")])
11286 ;; See comment above `ashldi3' about how this works.
11288 (define_expand "ashrti3"
11289   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11290                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11291                                 (match_operand:QI 2 "nonmemory_operand" "")))
11292               (clobber (reg:CC FLAGS_REG))])]
11293   "TARGET_64BIT"
11295   if (! immediate_operand (operands[2], QImode))
11296     {
11297       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11298       DONE;
11299     }
11300   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11301   DONE;
11304 (define_insn "ashrti3_1"
11305   [(set (match_operand:TI 0 "register_operand" "=r")
11306         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11307                      (match_operand:QI 2 "register_operand" "c")))
11308    (clobber (match_scratch:DI 3 "=&r"))
11309    (clobber (reg:CC FLAGS_REG))]
11310   "TARGET_64BIT"
11311   "#"
11312   [(set_attr "type" "multi")])
11314 (define_insn "*ashrti3_2"
11315   [(set (match_operand:TI 0 "register_operand" "=r")
11316         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11317                      (match_operand:QI 2 "immediate_operand" "O")))
11318    (clobber (reg:CC FLAGS_REG))]
11319   "TARGET_64BIT"
11320   "#"
11321   [(set_attr "type" "multi")])
11323 (define_split
11324   [(set (match_operand:TI 0 "register_operand" "")
11325         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11326                      (match_operand:QI 2 "register_operand" "")))
11327    (clobber (match_scratch:DI 3 ""))
11328    (clobber (reg:CC FLAGS_REG))]
11329   "TARGET_64BIT && reload_completed"
11330   [(const_int 0)]
11331   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11333 (define_split
11334   [(set (match_operand:TI 0 "register_operand" "")
11335         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11336                      (match_operand:QI 2 "immediate_operand" "")))
11337    (clobber (reg:CC FLAGS_REG))]
11338   "TARGET_64BIT && reload_completed"
11339   [(const_int 0)]
11340   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11342 (define_insn "x86_64_shrd"
11343   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11344         (ior:DI (ashiftrt:DI (match_dup 0)
11345                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11346                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11347                   (minus:QI (const_int 64) (match_dup 2)))))
11348    (clobber (reg:CC FLAGS_REG))]
11349   "TARGET_64BIT"
11350   "@
11351    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11352    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11353   [(set_attr "type" "ishift")
11354    (set_attr "prefix_0f" "1")
11355    (set_attr "mode" "DI")
11356    (set_attr "athlon_decode" "vector")
11357    (set_attr "amdfam10_decode" "vector")])   
11359 (define_expand "ashrdi3"
11360   [(set (match_operand:DI 0 "shiftdi_operand" "")
11361         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11362                      (match_operand:QI 2 "nonmemory_operand" "")))]
11363   ""
11364   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11366 (define_insn "*ashrdi3_63_rex64"
11367   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11368         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11369                      (match_operand:DI 2 "const_int_operand" "i,i")))
11370    (clobber (reg:CC FLAGS_REG))]
11371   "TARGET_64BIT && INTVAL (operands[2]) == 63
11372    && (TARGET_USE_CLTD || optimize_size)
11373    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11374   "@
11375    {cqto|cqo}
11376    sar{q}\t{%2, %0|%0, %2}"
11377   [(set_attr "type" "imovx,ishift")
11378    (set_attr "prefix_0f" "0,*")
11379    (set_attr "length_immediate" "0,*")
11380    (set_attr "modrm" "0,1")
11381    (set_attr "mode" "DI")])
11383 (define_insn "*ashrdi3_1_one_bit_rex64"
11384   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11385         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11386                      (match_operand:QI 2 "const1_operand" "")))
11387    (clobber (reg:CC FLAGS_REG))]
11388   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11389    && (TARGET_SHIFT1 || optimize_size)"
11390   "sar{q}\t%0"
11391   [(set_attr "type" "ishift")
11392    (set (attr "length")
11393      (if_then_else (match_operand:DI 0 "register_operand" "")
11394         (const_string "2")
11395         (const_string "*")))])
11397 (define_insn "*ashrdi3_1_rex64"
11398   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11399         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11400                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11401    (clobber (reg:CC FLAGS_REG))]
11402   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11403   "@
11404    sar{q}\t{%2, %0|%0, %2}
11405    sar{q}\t{%b2, %0|%0, %b2}"
11406   [(set_attr "type" "ishift")
11407    (set_attr "mode" "DI")])
11409 ;; This pattern can't accept a variable shift count, since shifts by
11410 ;; zero don't affect the flags.  We assume that shifts by constant
11411 ;; zero are optimized away.
11412 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11413   [(set (reg FLAGS_REG)
11414         (compare
11415           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11416                        (match_operand:QI 2 "const1_operand" ""))
11417           (const_int 0)))
11418    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11419         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11420   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11421    && (TARGET_SHIFT1 || optimize_size)
11422    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11423   "sar{q}\t%0"
11424   [(set_attr "type" "ishift")
11425    (set (attr "length")
11426      (if_then_else (match_operand:DI 0 "register_operand" "")
11427         (const_string "2")
11428         (const_string "*")))])
11430 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11431   [(set (reg FLAGS_REG)
11432         (compare
11433           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11434                        (match_operand:QI 2 "const1_operand" ""))
11435           (const_int 0)))
11436    (clobber (match_scratch:DI 0 "=r"))]
11437   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11438    && (TARGET_SHIFT1 || optimize_size)
11439    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11440   "sar{q}\t%0"
11441   [(set_attr "type" "ishift")
11442    (set_attr "length" "2")])
11444 ;; This pattern can't accept a variable shift count, since shifts by
11445 ;; zero don't affect the flags.  We assume that shifts by constant
11446 ;; zero are optimized away.
11447 (define_insn "*ashrdi3_cmp_rex64"
11448   [(set (reg FLAGS_REG)
11449         (compare
11450           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11451                        (match_operand:QI 2 "const_int_operand" "n"))
11452           (const_int 0)))
11453    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11454         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11455   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11456    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11457    && (optimize_size
11458        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11459   "sar{q}\t{%2, %0|%0, %2}"
11460   [(set_attr "type" "ishift")
11461    (set_attr "mode" "DI")])
11463 (define_insn "*ashrdi3_cconly_rex64"
11464   [(set (reg FLAGS_REG)
11465         (compare
11466           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11467                        (match_operand:QI 2 "const_int_operand" "n"))
11468           (const_int 0)))
11469    (clobber (match_scratch:DI 0 "=r"))]
11470   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11471    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11472    && (optimize_size
11473        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11474   "sar{q}\t{%2, %0|%0, %2}"
11475   [(set_attr "type" "ishift")
11476    (set_attr "mode" "DI")])
11478 (define_insn "*ashrdi3_1"
11479   [(set (match_operand:DI 0 "register_operand" "=r")
11480         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11481                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11482    (clobber (reg:CC FLAGS_REG))]
11483   "!TARGET_64BIT"
11484   "#"
11485   [(set_attr "type" "multi")])
11487 ;; By default we don't ask for a scratch register, because when DImode
11488 ;; values are manipulated, registers are already at a premium.  But if
11489 ;; we have one handy, we won't turn it away.
11490 (define_peephole2
11491   [(match_scratch:SI 3 "r")
11492    (parallel [(set (match_operand:DI 0 "register_operand" "")
11493                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11494                                 (match_operand:QI 2 "nonmemory_operand" "")))
11495               (clobber (reg:CC FLAGS_REG))])
11496    (match_dup 3)]
11497   "!TARGET_64BIT && TARGET_CMOVE"
11498   [(const_int 0)]
11499   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11501 (define_split
11502   [(set (match_operand:DI 0 "register_operand" "")
11503         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11504                      (match_operand:QI 2 "nonmemory_operand" "")))
11505    (clobber (reg:CC FLAGS_REG))]
11506   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11507                      ? flow2_completed : reload_completed)"
11508   [(const_int 0)]
11509   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11511 (define_insn "x86_shrd_1"
11512   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11513         (ior:SI (ashiftrt:SI (match_dup 0)
11514                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11515                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11516                   (minus:QI (const_int 32) (match_dup 2)))))
11517    (clobber (reg:CC FLAGS_REG))]
11518   ""
11519   "@
11520    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11521    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11522   [(set_attr "type" "ishift")
11523    (set_attr "prefix_0f" "1")
11524    (set_attr "pent_pair" "np")
11525    (set_attr "mode" "SI")])
11527 (define_expand "x86_shift_adj_3"
11528   [(use (match_operand:SI 0 "register_operand" ""))
11529    (use (match_operand:SI 1 "register_operand" ""))
11530    (use (match_operand:QI 2 "register_operand" ""))]
11531   ""
11533   rtx label = gen_label_rtx ();
11534   rtx tmp;
11536   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11538   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11539   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11540   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11541                               gen_rtx_LABEL_REF (VOIDmode, label),
11542                               pc_rtx);
11543   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11544   JUMP_LABEL (tmp) = label;
11546   emit_move_insn (operands[0], operands[1]);
11547   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11549   emit_label (label);
11550   LABEL_NUSES (label) = 1;
11552   DONE;
11555 (define_insn "ashrsi3_31"
11556   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11557         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11558                      (match_operand:SI 2 "const_int_operand" "i,i")))
11559    (clobber (reg:CC FLAGS_REG))]
11560   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11561    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11562   "@
11563    {cltd|cdq}
11564    sar{l}\t{%2, %0|%0, %2}"
11565   [(set_attr "type" "imovx,ishift")
11566    (set_attr "prefix_0f" "0,*")
11567    (set_attr "length_immediate" "0,*")
11568    (set_attr "modrm" "0,1")
11569    (set_attr "mode" "SI")])
11571 (define_insn "*ashrsi3_31_zext"
11572   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11573         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11574                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11575    (clobber (reg:CC FLAGS_REG))]
11576   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11577    && INTVAL (operands[2]) == 31
11578    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11579   "@
11580    {cltd|cdq}
11581    sar{l}\t{%2, %k0|%k0, %2}"
11582   [(set_attr "type" "imovx,ishift")
11583    (set_attr "prefix_0f" "0,*")
11584    (set_attr "length_immediate" "0,*")
11585    (set_attr "modrm" "0,1")
11586    (set_attr "mode" "SI")])
11588 (define_expand "ashrsi3"
11589   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11590         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11591                      (match_operand:QI 2 "nonmemory_operand" "")))
11592    (clobber (reg:CC FLAGS_REG))]
11593   ""
11594   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11596 (define_insn "*ashrsi3_1_one_bit"
11597   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11598         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11599                      (match_operand:QI 2 "const1_operand" "")))
11600    (clobber (reg:CC FLAGS_REG))]
11601   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11602    && (TARGET_SHIFT1 || optimize_size)"
11603   "sar{l}\t%0"
11604   [(set_attr "type" "ishift")
11605    (set (attr "length")
11606      (if_then_else (match_operand:SI 0 "register_operand" "")
11607         (const_string "2")
11608         (const_string "*")))])
11610 (define_insn "*ashrsi3_1_one_bit_zext"
11611   [(set (match_operand:DI 0 "register_operand" "=r")
11612         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11613                                      (match_operand:QI 2 "const1_operand" ""))))
11614    (clobber (reg:CC FLAGS_REG))]
11615   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11616    && (TARGET_SHIFT1 || optimize_size)"
11617   "sar{l}\t%k0"
11618   [(set_attr "type" "ishift")
11619    (set_attr "length" "2")])
11621 (define_insn "*ashrsi3_1"
11622   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11623         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11624                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11625    (clobber (reg:CC FLAGS_REG))]
11626   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11627   "@
11628    sar{l}\t{%2, %0|%0, %2}
11629    sar{l}\t{%b2, %0|%0, %b2}"
11630   [(set_attr "type" "ishift")
11631    (set_attr "mode" "SI")])
11633 (define_insn "*ashrsi3_1_zext"
11634   [(set (match_operand:DI 0 "register_operand" "=r,r")
11635         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11636                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11637    (clobber (reg:CC FLAGS_REG))]
11638   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11639   "@
11640    sar{l}\t{%2, %k0|%k0, %2}
11641    sar{l}\t{%b2, %k0|%k0, %b2}"
11642   [(set_attr "type" "ishift")
11643    (set_attr "mode" "SI")])
11645 ;; This pattern can't accept a variable shift count, since shifts by
11646 ;; zero don't affect the flags.  We assume that shifts by constant
11647 ;; zero are optimized away.
11648 (define_insn "*ashrsi3_one_bit_cmp"
11649   [(set (reg FLAGS_REG)
11650         (compare
11651           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11652                        (match_operand:QI 2 "const1_operand" ""))
11653           (const_int 0)))
11654    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11655         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11656   "ix86_match_ccmode (insn, CCGOCmode)
11657    && (TARGET_SHIFT1 || optimize_size)
11658    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11659   "sar{l}\t%0"
11660   [(set_attr "type" "ishift")
11661    (set (attr "length")
11662      (if_then_else (match_operand:SI 0 "register_operand" "")
11663         (const_string "2")
11664         (const_string "*")))])
11666 (define_insn "*ashrsi3_one_bit_cconly"
11667   [(set (reg FLAGS_REG)
11668         (compare
11669           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11670                        (match_operand:QI 2 "const1_operand" ""))
11671           (const_int 0)))
11672    (clobber (match_scratch:SI 0 "=r"))]
11673   "ix86_match_ccmode (insn, CCGOCmode)
11674    && (TARGET_SHIFT1 || optimize_size)
11675    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11676   "sar{l}\t%0"
11677   [(set_attr "type" "ishift")
11678    (set_attr "length" "2")])
11680 (define_insn "*ashrsi3_one_bit_cmp_zext"
11681   [(set (reg FLAGS_REG)
11682         (compare
11683           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11684                        (match_operand:QI 2 "const1_operand" ""))
11685           (const_int 0)))
11686    (set (match_operand:DI 0 "register_operand" "=r")
11687         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11688   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11689    && (TARGET_SHIFT1 || optimize_size)
11690    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11691   "sar{l}\t%k0"
11692   [(set_attr "type" "ishift")
11693    (set_attr "length" "2")])
11695 ;; This pattern can't accept a variable shift count, since shifts by
11696 ;; zero don't affect the flags.  We assume that shifts by constant
11697 ;; zero are optimized away.
11698 (define_insn "*ashrsi3_cmp"
11699   [(set (reg FLAGS_REG)
11700         (compare
11701           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11702                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11703           (const_int 0)))
11704    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11705         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11706   "ix86_match_ccmode (insn, CCGOCmode)
11707    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11708    && (optimize_size
11709        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11710   "sar{l}\t{%2, %0|%0, %2}"
11711   [(set_attr "type" "ishift")
11712    (set_attr "mode" "SI")])
11714 (define_insn "*ashrsi3_cconly"
11715   [(set (reg FLAGS_REG)
11716         (compare
11717           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11718                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11719           (const_int 0)))
11720    (clobber (match_scratch:SI 0 "=r"))]
11721   "ix86_match_ccmode (insn, CCGOCmode)
11722    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11723    && (optimize_size
11724        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11725   "sar{l}\t{%2, %0|%0, %2}"
11726   [(set_attr "type" "ishift")
11727    (set_attr "mode" "SI")])
11729 (define_insn "*ashrsi3_cmp_zext"
11730   [(set (reg FLAGS_REG)
11731         (compare
11732           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11733                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11734           (const_int 0)))
11735    (set (match_operand:DI 0 "register_operand" "=r")
11736         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11737   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11738    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11739    && (optimize_size
11740        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11741   "sar{l}\t{%2, %k0|%k0, %2}"
11742   [(set_attr "type" "ishift")
11743    (set_attr "mode" "SI")])
11745 (define_expand "ashrhi3"
11746   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11747         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11748                      (match_operand:QI 2 "nonmemory_operand" "")))
11749    (clobber (reg:CC FLAGS_REG))]
11750   "TARGET_HIMODE_MATH"
11751   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11753 (define_insn "*ashrhi3_1_one_bit"
11754   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11755         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11756                      (match_operand:QI 2 "const1_operand" "")))
11757    (clobber (reg:CC FLAGS_REG))]
11758   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11759    && (TARGET_SHIFT1 || optimize_size)"
11760   "sar{w}\t%0"
11761   [(set_attr "type" "ishift")
11762    (set (attr "length")
11763      (if_then_else (match_operand 0 "register_operand" "")
11764         (const_string "2")
11765         (const_string "*")))])
11767 (define_insn "*ashrhi3_1"
11768   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11769         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11770                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11771    (clobber (reg:CC FLAGS_REG))]
11772   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11773   "@
11774    sar{w}\t{%2, %0|%0, %2}
11775    sar{w}\t{%b2, %0|%0, %b2}"
11776   [(set_attr "type" "ishift")
11777    (set_attr "mode" "HI")])
11779 ;; This pattern can't accept a variable shift count, since shifts by
11780 ;; zero don't affect the flags.  We assume that shifts by constant
11781 ;; zero are optimized away.
11782 (define_insn "*ashrhi3_one_bit_cmp"
11783   [(set (reg FLAGS_REG)
11784         (compare
11785           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11786                        (match_operand:QI 2 "const1_operand" ""))
11787           (const_int 0)))
11788    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11789         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11790   "ix86_match_ccmode (insn, CCGOCmode)
11791    && (TARGET_SHIFT1 || optimize_size)
11792    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11793   "sar{w}\t%0"
11794   [(set_attr "type" "ishift")
11795    (set (attr "length")
11796      (if_then_else (match_operand 0 "register_operand" "")
11797         (const_string "2")
11798         (const_string "*")))])
11800 (define_insn "*ashrhi3_one_bit_cconly"
11801   [(set (reg FLAGS_REG)
11802         (compare
11803           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11804                        (match_operand:QI 2 "const1_operand" ""))
11805           (const_int 0)))
11806    (clobber (match_scratch:HI 0 "=r"))]
11807   "ix86_match_ccmode (insn, CCGOCmode)
11808    && (TARGET_SHIFT1 || optimize_size)
11809    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11810   "sar{w}\t%0"
11811   [(set_attr "type" "ishift")
11812    (set_attr "length" "2")])
11814 ;; This pattern can't accept a variable shift count, since shifts by
11815 ;; zero don't affect the flags.  We assume that shifts by constant
11816 ;; zero are optimized away.
11817 (define_insn "*ashrhi3_cmp"
11818   [(set (reg FLAGS_REG)
11819         (compare
11820           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11821                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11822           (const_int 0)))
11823    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11824         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11825   "ix86_match_ccmode (insn, CCGOCmode)
11826    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11827    && (optimize_size
11828        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11829   "sar{w}\t{%2, %0|%0, %2}"
11830   [(set_attr "type" "ishift")
11831    (set_attr "mode" "HI")])
11833 (define_insn "*ashrhi3_cconly"
11834   [(set (reg FLAGS_REG)
11835         (compare
11836           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11837                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11838           (const_int 0)))
11839    (clobber (match_scratch:HI 0 "=r"))]
11840   "ix86_match_ccmode (insn, CCGOCmode)
11841    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11842    && (optimize_size
11843        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11844   "sar{w}\t{%2, %0|%0, %2}"
11845   [(set_attr "type" "ishift")
11846    (set_attr "mode" "HI")])
11848 (define_expand "ashrqi3"
11849   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11850         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11851                      (match_operand:QI 2 "nonmemory_operand" "")))
11852    (clobber (reg:CC FLAGS_REG))]
11853   "TARGET_QIMODE_MATH"
11854   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11856 (define_insn "*ashrqi3_1_one_bit"
11857   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11858         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11859                      (match_operand:QI 2 "const1_operand" "")))
11860    (clobber (reg:CC FLAGS_REG))]
11861   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11862    && (TARGET_SHIFT1 || optimize_size)"
11863   "sar{b}\t%0"
11864   [(set_attr "type" "ishift")
11865    (set (attr "length")
11866      (if_then_else (match_operand 0 "register_operand" "")
11867         (const_string "2")
11868         (const_string "*")))])
11870 (define_insn "*ashrqi3_1_one_bit_slp"
11871   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11872         (ashiftrt:QI (match_dup 0)
11873                      (match_operand:QI 1 "const1_operand" "")))
11874    (clobber (reg:CC FLAGS_REG))]
11875   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11876    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11877    && (TARGET_SHIFT1 || optimize_size)"
11878   "sar{b}\t%0"
11879   [(set_attr "type" "ishift1")
11880    (set (attr "length")
11881      (if_then_else (match_operand 0 "register_operand" "")
11882         (const_string "2")
11883         (const_string "*")))])
11885 (define_insn "*ashrqi3_1"
11886   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11887         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11888                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11889    (clobber (reg:CC FLAGS_REG))]
11890   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11891   "@
11892    sar{b}\t{%2, %0|%0, %2}
11893    sar{b}\t{%b2, %0|%0, %b2}"
11894   [(set_attr "type" "ishift")
11895    (set_attr "mode" "QI")])
11897 (define_insn "*ashrqi3_1_slp"
11898   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11899         (ashiftrt:QI (match_dup 0)
11900                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11901    (clobber (reg:CC FLAGS_REG))]
11902   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11903    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11904   "@
11905    sar{b}\t{%1, %0|%0, %1}
11906    sar{b}\t{%b1, %0|%0, %b1}"
11907   [(set_attr "type" "ishift1")
11908    (set_attr "mode" "QI")])
11910 ;; This pattern can't accept a variable shift count, since shifts by
11911 ;; zero don't affect the flags.  We assume that shifts by constant
11912 ;; zero are optimized away.
11913 (define_insn "*ashrqi3_one_bit_cmp"
11914   [(set (reg FLAGS_REG)
11915         (compare
11916           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11917                        (match_operand:QI 2 "const1_operand" "I"))
11918           (const_int 0)))
11919    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11920         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11921   "ix86_match_ccmode (insn, CCGOCmode)
11922    && (TARGET_SHIFT1 || optimize_size)
11923    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11924   "sar{b}\t%0"
11925   [(set_attr "type" "ishift")
11926    (set (attr "length")
11927      (if_then_else (match_operand 0 "register_operand" "")
11928         (const_string "2")
11929         (const_string "*")))])
11931 (define_insn "*ashrqi3_one_bit_cconly"
11932   [(set (reg FLAGS_REG)
11933         (compare
11934           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11935                        (match_operand:QI 2 "const1_operand" "I"))
11936           (const_int 0)))
11937    (clobber (match_scratch:QI 0 "=q"))]
11938   "ix86_match_ccmode (insn, CCGOCmode)
11939    && (TARGET_SHIFT1 || optimize_size)
11940    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11941   "sar{b}\t%0"
11942   [(set_attr "type" "ishift")
11943    (set_attr "length" "2")])
11945 ;; This pattern can't accept a variable shift count, since shifts by
11946 ;; zero don't affect the flags.  We assume that shifts by constant
11947 ;; zero are optimized away.
11948 (define_insn "*ashrqi3_cmp"
11949   [(set (reg FLAGS_REG)
11950         (compare
11951           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11952                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11953           (const_int 0)))
11954    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11955         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11956   "ix86_match_ccmode (insn, CCGOCmode)
11957    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11958    && (optimize_size
11959        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11960   "sar{b}\t{%2, %0|%0, %2}"
11961   [(set_attr "type" "ishift")
11962    (set_attr "mode" "QI")])
11964 (define_insn "*ashrqi3_cconly"
11965   [(set (reg FLAGS_REG)
11966         (compare
11967           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11968                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11969           (const_int 0)))
11970    (clobber (match_scratch:QI 0 "=q"))]
11971   "ix86_match_ccmode (insn, CCGOCmode)
11972    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11973    && (optimize_size
11974        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11975   "sar{b}\t{%2, %0|%0, %2}"
11976   [(set_attr "type" "ishift")
11977    (set_attr "mode" "QI")])
11980 ;; Logical shift instructions
11982 ;; See comment above `ashldi3' about how this works.
11984 (define_expand "lshrti3"
11985   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11986                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11987                                 (match_operand:QI 2 "nonmemory_operand" "")))
11988               (clobber (reg:CC FLAGS_REG))])]
11989   "TARGET_64BIT"
11991   if (! immediate_operand (operands[2], QImode))
11992     {
11993       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11994       DONE;
11995     }
11996   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11997   DONE;
12000 (define_insn "lshrti3_1"
12001   [(set (match_operand:TI 0 "register_operand" "=r")
12002         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12003                      (match_operand:QI 2 "register_operand" "c")))
12004    (clobber (match_scratch:DI 3 "=&r"))
12005    (clobber (reg:CC FLAGS_REG))]
12006   "TARGET_64BIT"
12007   "#"
12008   [(set_attr "type" "multi")])
12010 (define_insn "*lshrti3_2"
12011   [(set (match_operand:TI 0 "register_operand" "=r")
12012         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12013                      (match_operand:QI 2 "immediate_operand" "O")))
12014    (clobber (reg:CC FLAGS_REG))]
12015   "TARGET_64BIT"
12016   "#"
12017   [(set_attr "type" "multi")])
12019 (define_split
12020   [(set (match_operand:TI 0 "register_operand" "")
12021         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12022                      (match_operand:QI 2 "register_operand" "")))
12023    (clobber (match_scratch:DI 3 ""))
12024    (clobber (reg:CC FLAGS_REG))]
12025   "TARGET_64BIT && reload_completed"
12026   [(const_int 0)]
12027   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12029 (define_split
12030   [(set (match_operand:TI 0 "register_operand" "")
12031         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12032                      (match_operand:QI 2 "immediate_operand" "")))
12033    (clobber (reg:CC FLAGS_REG))]
12034   "TARGET_64BIT && reload_completed"
12035   [(const_int 0)]
12036   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12038 (define_expand "lshrdi3"
12039   [(set (match_operand:DI 0 "shiftdi_operand" "")
12040         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12041                      (match_operand:QI 2 "nonmemory_operand" "")))]
12042   ""
12043   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12045 (define_insn "*lshrdi3_1_one_bit_rex64"
12046   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12047         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12048                      (match_operand:QI 2 "const1_operand" "")))
12049    (clobber (reg:CC FLAGS_REG))]
12050   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12051    && (TARGET_SHIFT1 || optimize_size)"
12052   "shr{q}\t%0"
12053   [(set_attr "type" "ishift")
12054    (set (attr "length")
12055      (if_then_else (match_operand:DI 0 "register_operand" "")
12056         (const_string "2")
12057         (const_string "*")))])
12059 (define_insn "*lshrdi3_1_rex64"
12060   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12061         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12062                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12063    (clobber (reg:CC FLAGS_REG))]
12064   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12065   "@
12066    shr{q}\t{%2, %0|%0, %2}
12067    shr{q}\t{%b2, %0|%0, %b2}"
12068   [(set_attr "type" "ishift")
12069    (set_attr "mode" "DI")])
12071 ;; This pattern can't accept a variable shift count, since shifts by
12072 ;; zero don't affect the flags.  We assume that shifts by constant
12073 ;; zero are optimized away.
12074 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12075   [(set (reg FLAGS_REG)
12076         (compare
12077           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12078                        (match_operand:QI 2 "const1_operand" ""))
12079           (const_int 0)))
12080    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12081         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12082   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12083    && (TARGET_SHIFT1 || optimize_size)
12084    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12085   "shr{q}\t%0"
12086   [(set_attr "type" "ishift")
12087    (set (attr "length")
12088      (if_then_else (match_operand:DI 0 "register_operand" "")
12089         (const_string "2")
12090         (const_string "*")))])
12092 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12093   [(set (reg FLAGS_REG)
12094         (compare
12095           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12096                        (match_operand:QI 2 "const1_operand" ""))
12097           (const_int 0)))
12098    (clobber (match_scratch:DI 0 "=r"))]
12099   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12100    && (TARGET_SHIFT1 || optimize_size)
12101    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12102   "shr{q}\t%0"
12103   [(set_attr "type" "ishift")
12104    (set_attr "length" "2")])
12106 ;; This pattern can't accept a variable shift count, since shifts by
12107 ;; zero don't affect the flags.  We assume that shifts by constant
12108 ;; zero are optimized away.
12109 (define_insn "*lshrdi3_cmp_rex64"
12110   [(set (reg FLAGS_REG)
12111         (compare
12112           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12113                        (match_operand:QI 2 "const_int_operand" "e"))
12114           (const_int 0)))
12115    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12116         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12117   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12118    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12119    && (optimize_size
12120        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12121   "shr{q}\t{%2, %0|%0, %2}"
12122   [(set_attr "type" "ishift")
12123    (set_attr "mode" "DI")])
12125 (define_insn "*lshrdi3_cconly_rex64"
12126   [(set (reg FLAGS_REG)
12127         (compare
12128           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12129                        (match_operand:QI 2 "const_int_operand" "e"))
12130           (const_int 0)))
12131    (clobber (match_scratch:DI 0 "=r"))]
12132   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12133    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12134    && (optimize_size
12135        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12136   "shr{q}\t{%2, %0|%0, %2}"
12137   [(set_attr "type" "ishift")
12138    (set_attr "mode" "DI")])
12140 (define_insn "*lshrdi3_1"
12141   [(set (match_operand:DI 0 "register_operand" "=r")
12142         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12143                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12144    (clobber (reg:CC FLAGS_REG))]
12145   "!TARGET_64BIT"
12146   "#"
12147   [(set_attr "type" "multi")])
12149 ;; By default we don't ask for a scratch register, because when DImode
12150 ;; values are manipulated, registers are already at a premium.  But if
12151 ;; we have one handy, we won't turn it away.
12152 (define_peephole2
12153   [(match_scratch:SI 3 "r")
12154    (parallel [(set (match_operand:DI 0 "register_operand" "")
12155                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12156                                 (match_operand:QI 2 "nonmemory_operand" "")))
12157               (clobber (reg:CC FLAGS_REG))])
12158    (match_dup 3)]
12159   "!TARGET_64BIT && TARGET_CMOVE"
12160   [(const_int 0)]
12161   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12163 (define_split
12164   [(set (match_operand:DI 0 "register_operand" "")
12165         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12166                      (match_operand:QI 2 "nonmemory_operand" "")))
12167    (clobber (reg:CC FLAGS_REG))]
12168   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12169                      ? flow2_completed : reload_completed)"
12170   [(const_int 0)]
12171   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12173 (define_expand "lshrsi3"
12174   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12175         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12176                      (match_operand:QI 2 "nonmemory_operand" "")))
12177    (clobber (reg:CC FLAGS_REG))]
12178   ""
12179   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12181 (define_insn "*lshrsi3_1_one_bit"
12182   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12183         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12184                      (match_operand:QI 2 "const1_operand" "")))
12185    (clobber (reg:CC FLAGS_REG))]
12186   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12187    && (TARGET_SHIFT1 || optimize_size)"
12188   "shr{l}\t%0"
12189   [(set_attr "type" "ishift")
12190    (set (attr "length")
12191      (if_then_else (match_operand:SI 0 "register_operand" "")
12192         (const_string "2")
12193         (const_string "*")))])
12195 (define_insn "*lshrsi3_1_one_bit_zext"
12196   [(set (match_operand:DI 0 "register_operand" "=r")
12197         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12198                      (match_operand:QI 2 "const1_operand" "")))
12199    (clobber (reg:CC FLAGS_REG))]
12200   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12201    && (TARGET_SHIFT1 || optimize_size)"
12202   "shr{l}\t%k0"
12203   [(set_attr "type" "ishift")
12204    (set_attr "length" "2")])
12206 (define_insn "*lshrsi3_1"
12207   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12208         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12209                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12210    (clobber (reg:CC FLAGS_REG))]
12211   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12212   "@
12213    shr{l}\t{%2, %0|%0, %2}
12214    shr{l}\t{%b2, %0|%0, %b2}"
12215   [(set_attr "type" "ishift")
12216    (set_attr "mode" "SI")])
12218 (define_insn "*lshrsi3_1_zext"
12219   [(set (match_operand:DI 0 "register_operand" "=r,r")
12220         (zero_extend:DI
12221           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12222                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12223    (clobber (reg:CC FLAGS_REG))]
12224   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12225   "@
12226    shr{l}\t{%2, %k0|%k0, %2}
12227    shr{l}\t{%b2, %k0|%k0, %b2}"
12228   [(set_attr "type" "ishift")
12229    (set_attr "mode" "SI")])
12231 ;; This pattern can't accept a variable shift count, since shifts by
12232 ;; zero don't affect the flags.  We assume that shifts by constant
12233 ;; zero are optimized away.
12234 (define_insn "*lshrsi3_one_bit_cmp"
12235   [(set (reg FLAGS_REG)
12236         (compare
12237           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12238                        (match_operand:QI 2 "const1_operand" ""))
12239           (const_int 0)))
12240    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12241         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12242   "ix86_match_ccmode (insn, CCGOCmode)
12243    && (TARGET_SHIFT1 || optimize_size)
12244    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12245   "shr{l}\t%0"
12246   [(set_attr "type" "ishift")
12247    (set (attr "length")
12248      (if_then_else (match_operand:SI 0 "register_operand" "")
12249         (const_string "2")
12250         (const_string "*")))])
12252 (define_insn "*lshrsi3_one_bit_cconly"
12253   [(set (reg FLAGS_REG)
12254         (compare
12255           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12256                        (match_operand:QI 2 "const1_operand" ""))
12257           (const_int 0)))
12258    (clobber (match_scratch:SI 0 "=r"))]
12259   "ix86_match_ccmode (insn, CCGOCmode)
12260    && (TARGET_SHIFT1 || optimize_size)
12261    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12262   "shr{l}\t%0"
12263   [(set_attr "type" "ishift")
12264    (set_attr "length" "2")])
12266 (define_insn "*lshrsi3_cmp_one_bit_zext"
12267   [(set (reg FLAGS_REG)
12268         (compare
12269           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12270                        (match_operand:QI 2 "const1_operand" ""))
12271           (const_int 0)))
12272    (set (match_operand:DI 0 "register_operand" "=r")
12273         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12274   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12275    && (TARGET_SHIFT1 || optimize_size)
12276    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12277   "shr{l}\t%k0"
12278   [(set_attr "type" "ishift")
12279    (set_attr "length" "2")])
12281 ;; This pattern can't accept a variable shift count, since shifts by
12282 ;; zero don't affect the flags.  We assume that shifts by constant
12283 ;; zero are optimized away.
12284 (define_insn "*lshrsi3_cmp"
12285   [(set (reg FLAGS_REG)
12286         (compare
12287           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12288                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12289           (const_int 0)))
12290    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12291         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12292   "ix86_match_ccmode (insn, CCGOCmode)
12293    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12294    && (optimize_size
12295        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12296   "shr{l}\t{%2, %0|%0, %2}"
12297   [(set_attr "type" "ishift")
12298    (set_attr "mode" "SI")])
12300 (define_insn "*lshrsi3_cconly"
12301   [(set (reg FLAGS_REG)
12302       (compare
12303         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12304                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12305         (const_int 0)))
12306    (clobber (match_scratch:SI 0 "=r"))]
12307   "ix86_match_ccmode (insn, CCGOCmode)
12308    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12309    && (optimize_size
12310        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12311   "shr{l}\t{%2, %0|%0, %2}"
12312   [(set_attr "type" "ishift")
12313    (set_attr "mode" "SI")])
12315 (define_insn "*lshrsi3_cmp_zext"
12316   [(set (reg FLAGS_REG)
12317         (compare
12318           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12319                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12320           (const_int 0)))
12321    (set (match_operand:DI 0 "register_operand" "=r")
12322         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12323   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12324    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12325    && (optimize_size
12326        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12327   "shr{l}\t{%2, %k0|%k0, %2}"
12328   [(set_attr "type" "ishift")
12329    (set_attr "mode" "SI")])
12331 (define_expand "lshrhi3"
12332   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12333         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12334                      (match_operand:QI 2 "nonmemory_operand" "")))
12335    (clobber (reg:CC FLAGS_REG))]
12336   "TARGET_HIMODE_MATH"
12337   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12339 (define_insn "*lshrhi3_1_one_bit"
12340   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12341         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12342                      (match_operand:QI 2 "const1_operand" "")))
12343    (clobber (reg:CC FLAGS_REG))]
12344   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12345    && (TARGET_SHIFT1 || optimize_size)"
12346   "shr{w}\t%0"
12347   [(set_attr "type" "ishift")
12348    (set (attr "length")
12349      (if_then_else (match_operand 0 "register_operand" "")
12350         (const_string "2")
12351         (const_string "*")))])
12353 (define_insn "*lshrhi3_1"
12354   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12355         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12356                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12357    (clobber (reg:CC FLAGS_REG))]
12358   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12359   "@
12360    shr{w}\t{%2, %0|%0, %2}
12361    shr{w}\t{%b2, %0|%0, %b2}"
12362   [(set_attr "type" "ishift")
12363    (set_attr "mode" "HI")])
12365 ;; This pattern can't accept a variable shift count, since shifts by
12366 ;; zero don't affect the flags.  We assume that shifts by constant
12367 ;; zero are optimized away.
12368 (define_insn "*lshrhi3_one_bit_cmp"
12369   [(set (reg FLAGS_REG)
12370         (compare
12371           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12372                        (match_operand:QI 2 "const1_operand" ""))
12373           (const_int 0)))
12374    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12375         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12376   "ix86_match_ccmode (insn, CCGOCmode)
12377    && (TARGET_SHIFT1 || optimize_size)
12378    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12379   "shr{w}\t%0"
12380   [(set_attr "type" "ishift")
12381    (set (attr "length")
12382      (if_then_else (match_operand:SI 0 "register_operand" "")
12383         (const_string "2")
12384         (const_string "*")))])
12386 (define_insn "*lshrhi3_one_bit_cconly"
12387   [(set (reg FLAGS_REG)
12388         (compare
12389           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12390                        (match_operand:QI 2 "const1_operand" ""))
12391           (const_int 0)))
12392    (clobber (match_scratch:HI 0 "=r"))]
12393   "ix86_match_ccmode (insn, CCGOCmode)
12394    && (TARGET_SHIFT1 || optimize_size)
12395    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12396   "shr{w}\t%0"
12397   [(set_attr "type" "ishift")
12398    (set_attr "length" "2")])
12400 ;; This pattern can't accept a variable shift count, since shifts by
12401 ;; zero don't affect the flags.  We assume that shifts by constant
12402 ;; zero are optimized away.
12403 (define_insn "*lshrhi3_cmp"
12404   [(set (reg FLAGS_REG)
12405         (compare
12406           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12407                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12408           (const_int 0)))
12409    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12410         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12411   "ix86_match_ccmode (insn, CCGOCmode)
12412    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12413    && (optimize_size
12414        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12415   "shr{w}\t{%2, %0|%0, %2}"
12416   [(set_attr "type" "ishift")
12417    (set_attr "mode" "HI")])
12419 (define_insn "*lshrhi3_cconly"
12420   [(set (reg FLAGS_REG)
12421         (compare
12422           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12423                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12424           (const_int 0)))
12425    (clobber (match_scratch:HI 0 "=r"))]
12426   "ix86_match_ccmode (insn, CCGOCmode)
12427    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12428    && (optimize_size
12429        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12430   "shr{w}\t{%2, %0|%0, %2}"
12431   [(set_attr "type" "ishift")
12432    (set_attr "mode" "HI")])
12434 (define_expand "lshrqi3"
12435   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12436         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12437                      (match_operand:QI 2 "nonmemory_operand" "")))
12438    (clobber (reg:CC FLAGS_REG))]
12439   "TARGET_QIMODE_MATH"
12440   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12442 (define_insn "*lshrqi3_1_one_bit"
12443   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12444         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12445                      (match_operand:QI 2 "const1_operand" "")))
12446    (clobber (reg:CC FLAGS_REG))]
12447   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12448    && (TARGET_SHIFT1 || optimize_size)"
12449   "shr{b}\t%0"
12450   [(set_attr "type" "ishift")
12451    (set (attr "length")
12452      (if_then_else (match_operand 0 "register_operand" "")
12453         (const_string "2")
12454         (const_string "*")))])
12456 (define_insn "*lshrqi3_1_one_bit_slp"
12457   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12458         (lshiftrt:QI (match_dup 0)
12459                      (match_operand:QI 1 "const1_operand" "")))
12460    (clobber (reg:CC FLAGS_REG))]
12461   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12462    && (TARGET_SHIFT1 || optimize_size)"
12463   "shr{b}\t%0"
12464   [(set_attr "type" "ishift1")
12465    (set (attr "length")
12466      (if_then_else (match_operand 0 "register_operand" "")
12467         (const_string "2")
12468         (const_string "*")))])
12470 (define_insn "*lshrqi3_1"
12471   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12472         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12473                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12474    (clobber (reg:CC FLAGS_REG))]
12475   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12476   "@
12477    shr{b}\t{%2, %0|%0, %2}
12478    shr{b}\t{%b2, %0|%0, %b2}"
12479   [(set_attr "type" "ishift")
12480    (set_attr "mode" "QI")])
12482 (define_insn "*lshrqi3_1_slp"
12483   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12484         (lshiftrt:QI (match_dup 0)
12485                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12486    (clobber (reg:CC FLAGS_REG))]
12487   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12488    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12489   "@
12490    shr{b}\t{%1, %0|%0, %1}
12491    shr{b}\t{%b1, %0|%0, %b1}"
12492   [(set_attr "type" "ishift1")
12493    (set_attr "mode" "QI")])
12495 ;; This pattern can't accept a variable shift count, since shifts by
12496 ;; zero don't affect the flags.  We assume that shifts by constant
12497 ;; zero are optimized away.
12498 (define_insn "*lshrqi2_one_bit_cmp"
12499   [(set (reg FLAGS_REG)
12500         (compare
12501           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12502                        (match_operand:QI 2 "const1_operand" ""))
12503           (const_int 0)))
12504    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12505         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12506   "ix86_match_ccmode (insn, CCGOCmode)
12507    && (TARGET_SHIFT1 || optimize_size)
12508    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12509   "shr{b}\t%0"
12510   [(set_attr "type" "ishift")
12511    (set (attr "length")
12512      (if_then_else (match_operand:SI 0 "register_operand" "")
12513         (const_string "2")
12514         (const_string "*")))])
12516 (define_insn "*lshrqi2_one_bit_cconly"
12517   [(set (reg FLAGS_REG)
12518         (compare
12519           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12520                        (match_operand:QI 2 "const1_operand" ""))
12521           (const_int 0)))
12522    (clobber (match_scratch:QI 0 "=q"))]
12523   "ix86_match_ccmode (insn, CCGOCmode)
12524    && (TARGET_SHIFT1 || optimize_size)
12525    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12526   "shr{b}\t%0"
12527   [(set_attr "type" "ishift")
12528    (set_attr "length" "2")])
12530 ;; This pattern can't accept a variable shift count, since shifts by
12531 ;; zero don't affect the flags.  We assume that shifts by constant
12532 ;; zero are optimized away.
12533 (define_insn "*lshrqi2_cmp"
12534   [(set (reg FLAGS_REG)
12535         (compare
12536           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12537                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12538           (const_int 0)))
12539    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12540         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12541   "ix86_match_ccmode (insn, CCGOCmode)
12542    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12543    && (optimize_size
12544        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12545   "shr{b}\t{%2, %0|%0, %2}"
12546   [(set_attr "type" "ishift")
12547    (set_attr "mode" "QI")])
12549 (define_insn "*lshrqi2_cconly"
12550   [(set (reg FLAGS_REG)
12551         (compare
12552           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12553                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12554           (const_int 0)))
12555    (clobber (match_scratch:QI 0 "=q"))]
12556   "ix86_match_ccmode (insn, CCGOCmode)
12557    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12558    && (optimize_size
12559        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12560   "shr{b}\t{%2, %0|%0, %2}"
12561   [(set_attr "type" "ishift")
12562    (set_attr "mode" "QI")])
12564 ;; Rotate instructions
12566 (define_expand "rotldi3"
12567   [(set (match_operand:DI 0 "shiftdi_operand" "")
12568         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12569                    (match_operand:QI 2 "nonmemory_operand" "")))
12570    (clobber (reg:CC FLAGS_REG))]
12571  ""
12573   if (TARGET_64BIT)
12574     {
12575       ix86_expand_binary_operator (ROTATE, DImode, operands);
12576       DONE;
12577     }
12578   if (!const_1_to_31_operand (operands[2], VOIDmode))
12579     FAIL;
12580   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12581   DONE;
12584 ;; Implement rotation using two double-precision shift instructions
12585 ;; and a scratch register.
12586 (define_insn_and_split "ix86_rotldi3"
12587  [(set (match_operand:DI 0 "register_operand" "=r")
12588        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12589                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12590   (clobber (reg:CC FLAGS_REG))
12591   (clobber (match_scratch:SI 3 "=&r"))]
12592  "!TARGET_64BIT"
12593  ""
12594  "&& reload_completed"
12595  [(set (match_dup 3) (match_dup 4))
12596   (parallel
12597    [(set (match_dup 4)
12598          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12599                  (lshiftrt:SI (match_dup 5)
12600                               (minus:QI (const_int 32) (match_dup 2)))))
12601     (clobber (reg:CC FLAGS_REG))])
12602   (parallel
12603    [(set (match_dup 5)
12604          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12605                  (lshiftrt:SI (match_dup 3)
12606                               (minus:QI (const_int 32) (match_dup 2)))))
12607     (clobber (reg:CC FLAGS_REG))])]
12608  "split_di (operands, 1, operands + 4, operands + 5);")
12610 (define_insn "*rotlsi3_1_one_bit_rex64"
12611   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12612         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12613                    (match_operand:QI 2 "const1_operand" "")))
12614    (clobber (reg:CC FLAGS_REG))]
12615   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12616    && (TARGET_SHIFT1 || optimize_size)"
12617   "rol{q}\t%0"
12618   [(set_attr "type" "rotate")
12619    (set (attr "length")
12620      (if_then_else (match_operand:DI 0 "register_operand" "")
12621         (const_string "2")
12622         (const_string "*")))])
12624 (define_insn "*rotldi3_1_rex64"
12625   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12626         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12627                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12628    (clobber (reg:CC FLAGS_REG))]
12629   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12630   "@
12631    rol{q}\t{%2, %0|%0, %2}
12632    rol{q}\t{%b2, %0|%0, %b2}"
12633   [(set_attr "type" "rotate")
12634    (set_attr "mode" "DI")])
12636 (define_expand "rotlsi3"
12637   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12638         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12639                    (match_operand:QI 2 "nonmemory_operand" "")))
12640    (clobber (reg:CC FLAGS_REG))]
12641   ""
12642   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12644 (define_insn "*rotlsi3_1_one_bit"
12645   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12646         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12647                    (match_operand:QI 2 "const1_operand" "")))
12648    (clobber (reg:CC FLAGS_REG))]
12649   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12650    && (TARGET_SHIFT1 || optimize_size)"
12651   "rol{l}\t%0"
12652   [(set_attr "type" "rotate")
12653    (set (attr "length")
12654      (if_then_else (match_operand:SI 0 "register_operand" "")
12655         (const_string "2")
12656         (const_string "*")))])
12658 (define_insn "*rotlsi3_1_one_bit_zext"
12659   [(set (match_operand:DI 0 "register_operand" "=r")
12660         (zero_extend:DI
12661           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12662                      (match_operand:QI 2 "const1_operand" ""))))
12663    (clobber (reg:CC FLAGS_REG))]
12664   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12665    && (TARGET_SHIFT1 || optimize_size)"
12666   "rol{l}\t%k0"
12667   [(set_attr "type" "rotate")
12668    (set_attr "length" "2")])
12670 (define_insn "*rotlsi3_1"
12671   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12672         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12673                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12674    (clobber (reg:CC FLAGS_REG))]
12675   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12676   "@
12677    rol{l}\t{%2, %0|%0, %2}
12678    rol{l}\t{%b2, %0|%0, %b2}"
12679   [(set_attr "type" "rotate")
12680    (set_attr "mode" "SI")])
12682 (define_insn "*rotlsi3_1_zext"
12683   [(set (match_operand:DI 0 "register_operand" "=r,r")
12684         (zero_extend:DI
12685           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12686                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12687    (clobber (reg:CC FLAGS_REG))]
12688   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12689   "@
12690    rol{l}\t{%2, %k0|%k0, %2}
12691    rol{l}\t{%b2, %k0|%k0, %b2}"
12692   [(set_attr "type" "rotate")
12693    (set_attr "mode" "SI")])
12695 (define_expand "rotlhi3"
12696   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12697         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12698                    (match_operand:QI 2 "nonmemory_operand" "")))
12699    (clobber (reg:CC FLAGS_REG))]
12700   "TARGET_HIMODE_MATH"
12701   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12703 (define_insn "*rotlhi3_1_one_bit"
12704   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12705         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12706                    (match_operand:QI 2 "const1_operand" "")))
12707    (clobber (reg:CC FLAGS_REG))]
12708   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12709    && (TARGET_SHIFT1 || optimize_size)"
12710   "rol{w}\t%0"
12711   [(set_attr "type" "rotate")
12712    (set (attr "length")
12713      (if_then_else (match_operand 0 "register_operand" "")
12714         (const_string "2")
12715         (const_string "*")))])
12717 (define_insn "*rotlhi3_1"
12718   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12719         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12720                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12721    (clobber (reg:CC FLAGS_REG))]
12722   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12723   "@
12724    rol{w}\t{%2, %0|%0, %2}
12725    rol{w}\t{%b2, %0|%0, %b2}"
12726   [(set_attr "type" "rotate")
12727    (set_attr "mode" "HI")])
12729 (define_split
12730  [(set (match_operand:HI 0 "register_operand" "")
12731        (rotate:HI (match_dup 0) (const_int 8)))
12732   (clobber (reg:CC FLAGS_REG))]
12733  "reload_completed"
12734  [(parallel [(set (strict_low_part (match_dup 0))
12735                   (bswap:HI (match_dup 0)))
12736              (clobber (reg:CC FLAGS_REG))])]
12737  "")
12739 (define_expand "rotlqi3"
12740   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12741         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12742                    (match_operand:QI 2 "nonmemory_operand" "")))
12743    (clobber (reg:CC FLAGS_REG))]
12744   "TARGET_QIMODE_MATH"
12745   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12747 (define_insn "*rotlqi3_1_one_bit_slp"
12748   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12749         (rotate:QI (match_dup 0)
12750                    (match_operand:QI 1 "const1_operand" "")))
12751    (clobber (reg:CC FLAGS_REG))]
12752   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12753    && (TARGET_SHIFT1 || optimize_size)"
12754   "rol{b}\t%0"
12755   [(set_attr "type" "rotate1")
12756    (set (attr "length")
12757      (if_then_else (match_operand 0 "register_operand" "")
12758         (const_string "2")
12759         (const_string "*")))])
12761 (define_insn "*rotlqi3_1_one_bit"
12762   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12763         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12764                    (match_operand:QI 2 "const1_operand" "")))
12765    (clobber (reg:CC FLAGS_REG))]
12766   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12767    && (TARGET_SHIFT1 || optimize_size)"
12768   "rol{b}\t%0"
12769   [(set_attr "type" "rotate")
12770    (set (attr "length")
12771      (if_then_else (match_operand 0 "register_operand" "")
12772         (const_string "2")
12773         (const_string "*")))])
12775 (define_insn "*rotlqi3_1_slp"
12776   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12777         (rotate:QI (match_dup 0)
12778                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12779    (clobber (reg:CC FLAGS_REG))]
12780   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12781    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12782   "@
12783    rol{b}\t{%1, %0|%0, %1}
12784    rol{b}\t{%b1, %0|%0, %b1}"
12785   [(set_attr "type" "rotate1")
12786    (set_attr "mode" "QI")])
12788 (define_insn "*rotlqi3_1"
12789   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12790         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12791                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12792    (clobber (reg:CC FLAGS_REG))]
12793   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12794   "@
12795    rol{b}\t{%2, %0|%0, %2}
12796    rol{b}\t{%b2, %0|%0, %b2}"
12797   [(set_attr "type" "rotate")
12798    (set_attr "mode" "QI")])
12800 (define_expand "rotrdi3"
12801   [(set (match_operand:DI 0 "shiftdi_operand" "")
12802         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12803                    (match_operand:QI 2 "nonmemory_operand" "")))
12804    (clobber (reg:CC FLAGS_REG))]
12805  ""
12807   if (TARGET_64BIT)
12808     {
12809       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12810       DONE;
12811     }
12812   if (!const_1_to_31_operand (operands[2], VOIDmode))
12813     FAIL;
12814   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12815   DONE;
12818 ;; Implement rotation using two double-precision shift instructions
12819 ;; and a scratch register.
12820 (define_insn_and_split "ix86_rotrdi3"
12821  [(set (match_operand:DI 0 "register_operand" "=r")
12822        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12823                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12824   (clobber (reg:CC FLAGS_REG))
12825   (clobber (match_scratch:SI 3 "=&r"))]
12826  "!TARGET_64BIT"
12827  ""
12828  "&& reload_completed"
12829  [(set (match_dup 3) (match_dup 4))
12830   (parallel
12831    [(set (match_dup 4)
12832          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12833                  (ashift:SI (match_dup 5)
12834                             (minus:QI (const_int 32) (match_dup 2)))))
12835     (clobber (reg:CC FLAGS_REG))])
12836   (parallel
12837    [(set (match_dup 5)
12838          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12839                  (ashift:SI (match_dup 3)
12840                             (minus:QI (const_int 32) (match_dup 2)))))
12841     (clobber (reg:CC FLAGS_REG))])]
12842  "split_di (operands, 1, operands + 4, operands + 5);")
12844 (define_insn "*rotrdi3_1_one_bit_rex64"
12845   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12846         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12847                      (match_operand:QI 2 "const1_operand" "")))
12848    (clobber (reg:CC FLAGS_REG))]
12849   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12850    && (TARGET_SHIFT1 || optimize_size)"
12851   "ror{q}\t%0"
12852   [(set_attr "type" "rotate")
12853    (set (attr "length")
12854      (if_then_else (match_operand:DI 0 "register_operand" "")
12855         (const_string "2")
12856         (const_string "*")))])
12858 (define_insn "*rotrdi3_1_rex64"
12859   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12860         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12861                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12862    (clobber (reg:CC FLAGS_REG))]
12863   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12864   "@
12865    ror{q}\t{%2, %0|%0, %2}
12866    ror{q}\t{%b2, %0|%0, %b2}"
12867   [(set_attr "type" "rotate")
12868    (set_attr "mode" "DI")])
12870 (define_expand "rotrsi3"
12871   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12872         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12873                      (match_operand:QI 2 "nonmemory_operand" "")))
12874    (clobber (reg:CC FLAGS_REG))]
12875   ""
12876   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12878 (define_insn "*rotrsi3_1_one_bit"
12879   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12880         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12881                      (match_operand:QI 2 "const1_operand" "")))
12882    (clobber (reg:CC FLAGS_REG))]
12883   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12884    && (TARGET_SHIFT1 || optimize_size)"
12885   "ror{l}\t%0"
12886   [(set_attr "type" "rotate")
12887    (set (attr "length")
12888      (if_then_else (match_operand:SI 0 "register_operand" "")
12889         (const_string "2")
12890         (const_string "*")))])
12892 (define_insn "*rotrsi3_1_one_bit_zext"
12893   [(set (match_operand:DI 0 "register_operand" "=r")
12894         (zero_extend:DI
12895           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12896                        (match_operand:QI 2 "const1_operand" ""))))
12897    (clobber (reg:CC FLAGS_REG))]
12898   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12899    && (TARGET_SHIFT1 || optimize_size)"
12900   "ror{l}\t%k0"
12901   [(set_attr "type" "rotate")
12902    (set (attr "length")
12903      (if_then_else (match_operand:SI 0 "register_operand" "")
12904         (const_string "2")
12905         (const_string "*")))])
12907 (define_insn "*rotrsi3_1"
12908   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12909         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12910                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12911    (clobber (reg:CC FLAGS_REG))]
12912   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12913   "@
12914    ror{l}\t{%2, %0|%0, %2}
12915    ror{l}\t{%b2, %0|%0, %b2}"
12916   [(set_attr "type" "rotate")
12917    (set_attr "mode" "SI")])
12919 (define_insn "*rotrsi3_1_zext"
12920   [(set (match_operand:DI 0 "register_operand" "=r,r")
12921         (zero_extend:DI
12922           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12923                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12924    (clobber (reg:CC FLAGS_REG))]
12925   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12926   "@
12927    ror{l}\t{%2, %k0|%k0, %2}
12928    ror{l}\t{%b2, %k0|%k0, %b2}"
12929   [(set_attr "type" "rotate")
12930    (set_attr "mode" "SI")])
12932 (define_expand "rotrhi3"
12933   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12934         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12935                      (match_operand:QI 2 "nonmemory_operand" "")))
12936    (clobber (reg:CC FLAGS_REG))]
12937   "TARGET_HIMODE_MATH"
12938   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12940 (define_insn "*rotrhi3_one_bit"
12941   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12942         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12943                      (match_operand:QI 2 "const1_operand" "")))
12944    (clobber (reg:CC FLAGS_REG))]
12945   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12946    && (TARGET_SHIFT1 || optimize_size)"
12947   "ror{w}\t%0"
12948   [(set_attr "type" "rotate")
12949    (set (attr "length")
12950      (if_then_else (match_operand 0 "register_operand" "")
12951         (const_string "2")
12952         (const_string "*")))])
12954 (define_insn "*rotrhi3_1"
12955   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12956         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12957                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12958    (clobber (reg:CC FLAGS_REG))]
12959   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12960   "@
12961    ror{w}\t{%2, %0|%0, %2}
12962    ror{w}\t{%b2, %0|%0, %b2}"
12963   [(set_attr "type" "rotate")
12964    (set_attr "mode" "HI")])
12966 (define_split
12967  [(set (match_operand:HI 0 "register_operand" "")
12968        (rotatert:HI (match_dup 0) (const_int 8)))
12969   (clobber (reg:CC FLAGS_REG))]
12970  "reload_completed"
12971  [(parallel [(set (strict_low_part (match_dup 0))
12972                   (bswap:HI (match_dup 0)))
12973              (clobber (reg:CC FLAGS_REG))])]
12974  "")
12976 (define_expand "rotrqi3"
12977   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12978         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12979                      (match_operand:QI 2 "nonmemory_operand" "")))
12980    (clobber (reg:CC FLAGS_REG))]
12981   "TARGET_QIMODE_MATH"
12982   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12984 (define_insn "*rotrqi3_1_one_bit"
12985   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12986         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12987                      (match_operand:QI 2 "const1_operand" "")))
12988    (clobber (reg:CC FLAGS_REG))]
12989   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12990    && (TARGET_SHIFT1 || optimize_size)"
12991   "ror{b}\t%0"
12992   [(set_attr "type" "rotate")
12993    (set (attr "length")
12994      (if_then_else (match_operand 0 "register_operand" "")
12995         (const_string "2")
12996         (const_string "*")))])
12998 (define_insn "*rotrqi3_1_one_bit_slp"
12999   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13000         (rotatert:QI (match_dup 0)
13001                      (match_operand:QI 1 "const1_operand" "")))
13002    (clobber (reg:CC FLAGS_REG))]
13003   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13004    && (TARGET_SHIFT1 || optimize_size)"
13005   "ror{b}\t%0"
13006   [(set_attr "type" "rotate1")
13007    (set (attr "length")
13008      (if_then_else (match_operand 0 "register_operand" "")
13009         (const_string "2")
13010         (const_string "*")))])
13012 (define_insn "*rotrqi3_1"
13013   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13014         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13015                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13016    (clobber (reg:CC FLAGS_REG))]
13017   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13018   "@
13019    ror{b}\t{%2, %0|%0, %2}
13020    ror{b}\t{%b2, %0|%0, %b2}"
13021   [(set_attr "type" "rotate")
13022    (set_attr "mode" "QI")])
13024 (define_insn "*rotrqi3_1_slp"
13025   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13026         (rotatert:QI (match_dup 0)
13027                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13028    (clobber (reg:CC FLAGS_REG))]
13029   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13030    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13031   "@
13032    ror{b}\t{%1, %0|%0, %1}
13033    ror{b}\t{%b1, %0|%0, %b1}"
13034   [(set_attr "type" "rotate1")
13035    (set_attr "mode" "QI")])
13037 ;; Bit set / bit test instructions
13039 (define_expand "extv"
13040   [(set (match_operand:SI 0 "register_operand" "")
13041         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13042                          (match_operand:SI 2 "const8_operand" "")
13043                          (match_operand:SI 3 "const8_operand" "")))]
13044   ""
13046   /* Handle extractions from %ah et al.  */
13047   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13048     FAIL;
13050   /* From mips.md: extract_bit_field doesn't verify that our source
13051      matches the predicate, so check it again here.  */
13052   if (! ext_register_operand (operands[1], VOIDmode))
13053     FAIL;
13056 (define_expand "extzv"
13057   [(set (match_operand:SI 0 "register_operand" "")
13058         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13059                          (match_operand:SI 2 "const8_operand" "")
13060                          (match_operand:SI 3 "const8_operand" "")))]
13061   ""
13063   /* Handle extractions from %ah et al.  */
13064   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13065     FAIL;
13067   /* From mips.md: extract_bit_field doesn't verify that our source
13068      matches the predicate, so check it again here.  */
13069   if (! ext_register_operand (operands[1], VOIDmode))
13070     FAIL;
13073 (define_expand "insv"
13074   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13075                       (match_operand 1 "const8_operand" "")
13076                       (match_operand 2 "const8_operand" ""))
13077         (match_operand 3 "register_operand" ""))]
13078   ""
13080   /* Handle insertions to %ah et al.  */
13081   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13082     FAIL;
13084   /* From mips.md: insert_bit_field doesn't verify that our source
13085      matches the predicate, so check it again here.  */
13086   if (! ext_register_operand (operands[0], VOIDmode))
13087     FAIL;
13089   if (TARGET_64BIT)
13090     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13091   else
13092     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13094   DONE;
13097 ;; %%% bts, btr, btc, bt.
13098 ;; In general these instructions are *slow* when applied to memory,
13099 ;; since they enforce atomic operation.  When applied to registers,
13100 ;; it depends on the cpu implementation.  They're never faster than
13101 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13102 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13103 ;; within the instruction itself, so operating on bits in the high
13104 ;; 32-bits of a register becomes easier.
13106 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13107 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13108 ;; negdf respectively, so they can never be disabled entirely.
13110 (define_insn "*btsq"
13111   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13112                          (const_int 1)
13113                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13114         (const_int 1))
13115    (clobber (reg:CC FLAGS_REG))]
13116   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13117   "bts{q} %1,%0"
13118   [(set_attr "type" "alu1")])
13120 (define_insn "*btrq"
13121   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13122                          (const_int 1)
13123                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13124         (const_int 0))
13125    (clobber (reg:CC FLAGS_REG))]
13126   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13127   "btr{q} %1,%0"
13128   [(set_attr "type" "alu1")])
13130 (define_insn "*btcq"
13131   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13132                          (const_int 1)
13133                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13134         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13135    (clobber (reg:CC FLAGS_REG))]
13136   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13137   "btc{q} %1,%0"
13138   [(set_attr "type" "alu1")])
13140 ;; Allow Nocona to avoid these instructions if a register is available.
13142 (define_peephole2
13143   [(match_scratch:DI 2 "r")
13144    (parallel [(set (zero_extract:DI
13145                      (match_operand:DI 0 "register_operand" "")
13146                      (const_int 1)
13147                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13148                    (const_int 1))
13149               (clobber (reg:CC FLAGS_REG))])]
13150   "TARGET_64BIT && !TARGET_USE_BT"
13151   [(const_int 0)]
13153   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13154   rtx op1;
13156   if (HOST_BITS_PER_WIDE_INT >= 64)
13157     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13158   else if (i < HOST_BITS_PER_WIDE_INT)
13159     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13160   else
13161     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13163   op1 = immed_double_const (lo, hi, DImode);
13164   if (i >= 31)
13165     {
13166       emit_move_insn (operands[2], op1);
13167       op1 = operands[2];
13168     }
13170   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13171   DONE;
13174 (define_peephole2
13175   [(match_scratch:DI 2 "r")
13176    (parallel [(set (zero_extract:DI
13177                      (match_operand:DI 0 "register_operand" "")
13178                      (const_int 1)
13179                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13180                    (const_int 0))
13181               (clobber (reg:CC FLAGS_REG))])]
13182   "TARGET_64BIT && !TARGET_USE_BT"
13183   [(const_int 0)]
13185   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13186   rtx op1;
13188   if (HOST_BITS_PER_WIDE_INT >= 64)
13189     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13190   else if (i < HOST_BITS_PER_WIDE_INT)
13191     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13192   else
13193     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13195   op1 = immed_double_const (~lo, ~hi, DImode);
13196   if (i >= 32)
13197     {
13198       emit_move_insn (operands[2], op1);
13199       op1 = operands[2];
13200     }
13202   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13203   DONE;
13206 (define_peephole2
13207   [(match_scratch:DI 2 "r")
13208    (parallel [(set (zero_extract:DI
13209                      (match_operand:DI 0 "register_operand" "")
13210                      (const_int 1)
13211                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13212               (not:DI (zero_extract:DI
13213                         (match_dup 0) (const_int 1) (match_dup 1))))
13214               (clobber (reg:CC FLAGS_REG))])]
13215   "TARGET_64BIT && !TARGET_USE_BT"
13216   [(const_int 0)]
13218   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13219   rtx op1;
13221   if (HOST_BITS_PER_WIDE_INT >= 64)
13222     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13223   else if (i < HOST_BITS_PER_WIDE_INT)
13224     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13225   else
13226     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13228   op1 = immed_double_const (lo, hi, DImode);
13229   if (i >= 31)
13230     {
13231       emit_move_insn (operands[2], op1);
13232       op1 = operands[2];
13233     }
13235   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13236   DONE;
13239 ;; Store-flag instructions.
13241 ;; For all sCOND expanders, also expand the compare or test insn that
13242 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13244 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13245 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13246 ;; way, which can later delete the movzx if only QImode is needed.
13248 (define_expand "seq"
13249   [(set (match_operand:QI 0 "register_operand" "")
13250         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251   ""
13252   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13254 (define_expand "sne"
13255   [(set (match_operand:QI 0 "register_operand" "")
13256         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257   ""
13258   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13260 (define_expand "sgt"
13261   [(set (match_operand:QI 0 "register_operand" "")
13262         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263   ""
13264   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13266 (define_expand "sgtu"
13267   [(set (match_operand:QI 0 "register_operand" "")
13268         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13269   ""
13270   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13272 (define_expand "slt"
13273   [(set (match_operand:QI 0 "register_operand" "")
13274         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13275   ""
13276   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13278 (define_expand "sltu"
13279   [(set (match_operand:QI 0 "register_operand" "")
13280         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13281   ""
13282   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13284 (define_expand "sge"
13285   [(set (match_operand:QI 0 "register_operand" "")
13286         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13287   ""
13288   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13290 (define_expand "sgeu"
13291   [(set (match_operand:QI 0 "register_operand" "")
13292         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13293   ""
13294   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13296 (define_expand "sle"
13297   [(set (match_operand:QI 0 "register_operand" "")
13298         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13299   ""
13300   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13302 (define_expand "sleu"
13303   [(set (match_operand:QI 0 "register_operand" "")
13304         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13305   ""
13306   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13308 (define_expand "sunordered"
13309   [(set (match_operand:QI 0 "register_operand" "")
13310         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13311   "TARGET_80387 || TARGET_SSE"
13312   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13314 (define_expand "sordered"
13315   [(set (match_operand:QI 0 "register_operand" "")
13316         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13317   "TARGET_80387"
13318   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13320 (define_expand "suneq"
13321   [(set (match_operand:QI 0 "register_operand" "")
13322         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13323   "TARGET_80387 || TARGET_SSE"
13324   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13326 (define_expand "sunge"
13327   [(set (match_operand:QI 0 "register_operand" "")
13328         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13329   "TARGET_80387 || TARGET_SSE"
13330   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13332 (define_expand "sungt"
13333   [(set (match_operand:QI 0 "register_operand" "")
13334         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13335   "TARGET_80387 || TARGET_SSE"
13336   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13338 (define_expand "sunle"
13339   [(set (match_operand:QI 0 "register_operand" "")
13340         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13341   "TARGET_80387 || TARGET_SSE"
13342   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13344 (define_expand "sunlt"
13345   [(set (match_operand:QI 0 "register_operand" "")
13346         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13347   "TARGET_80387 || TARGET_SSE"
13348   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13350 (define_expand "sltgt"
13351   [(set (match_operand:QI 0 "register_operand" "")
13352         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13353   "TARGET_80387 || TARGET_SSE"
13354   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13356 (define_insn "*setcc_1"
13357   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13358         (match_operator:QI 1 "ix86_comparison_operator"
13359           [(reg FLAGS_REG) (const_int 0)]))]
13360   ""
13361   "set%C1\t%0"
13362   [(set_attr "type" "setcc")
13363    (set_attr "mode" "QI")])
13365 (define_insn "*setcc_2"
13366   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13367         (match_operator:QI 1 "ix86_comparison_operator"
13368           [(reg FLAGS_REG) (const_int 0)]))]
13369   ""
13370   "set%C1\t%0"
13371   [(set_attr "type" "setcc")
13372    (set_attr "mode" "QI")])
13374 ;; In general it is not safe to assume too much about CCmode registers,
13375 ;; so simplify-rtx stops when it sees a second one.  Under certain
13376 ;; conditions this is safe on x86, so help combine not create
13378 ;;      seta    %al
13379 ;;      testb   %al, %al
13380 ;;      sete    %al
13382 (define_split
13383   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13384         (ne:QI (match_operator 1 "ix86_comparison_operator"
13385                  [(reg FLAGS_REG) (const_int 0)])
13386             (const_int 0)))]
13387   ""
13388   [(set (match_dup 0) (match_dup 1))]
13390   PUT_MODE (operands[1], QImode);
13393 (define_split
13394   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13395         (ne:QI (match_operator 1 "ix86_comparison_operator"
13396                  [(reg FLAGS_REG) (const_int 0)])
13397             (const_int 0)))]
13398   ""
13399   [(set (match_dup 0) (match_dup 1))]
13401   PUT_MODE (operands[1], QImode);
13404 (define_split
13405   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13406         (eq:QI (match_operator 1 "ix86_comparison_operator"
13407                  [(reg FLAGS_REG) (const_int 0)])
13408             (const_int 0)))]
13409   ""
13410   [(set (match_dup 0) (match_dup 1))]
13412   rtx new_op1 = copy_rtx (operands[1]);
13413   operands[1] = new_op1;
13414   PUT_MODE (new_op1, QImode);
13415   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13416                                              GET_MODE (XEXP (new_op1, 0))));
13418   /* Make sure that (a) the CCmode we have for the flags is strong
13419      enough for the reversed compare or (b) we have a valid FP compare.  */
13420   if (! ix86_comparison_operator (new_op1, VOIDmode))
13421     FAIL;
13424 (define_split
13425   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13426         (eq:QI (match_operator 1 "ix86_comparison_operator"
13427                  [(reg FLAGS_REG) (const_int 0)])
13428             (const_int 0)))]
13429   ""
13430   [(set (match_dup 0) (match_dup 1))]
13432   rtx new_op1 = copy_rtx (operands[1]);
13433   operands[1] = new_op1;
13434   PUT_MODE (new_op1, QImode);
13435   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13436                                              GET_MODE (XEXP (new_op1, 0))));
13438   /* Make sure that (a) the CCmode we have for the flags is strong
13439      enough for the reversed compare or (b) we have a valid FP compare.  */
13440   if (! ix86_comparison_operator (new_op1, VOIDmode))
13441     FAIL;
13444 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13445 ;; subsequent logical operations are used to imitate conditional moves.
13446 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13447 ;; it directly.
13449 (define_insn "*sse_setccsf"
13450   [(set (match_operand:SF 0 "register_operand" "=x")
13451         (match_operator:SF 1 "sse_comparison_operator"
13452           [(match_operand:SF 2 "register_operand" "0")
13453            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13454   "TARGET_SSE"
13455   "cmp%D1ss\t{%3, %0|%0, %3}"
13456   [(set_attr "type" "ssecmp")
13457    (set_attr "mode" "SF")])
13459 (define_insn "*sse_setccdf"
13460   [(set (match_operand:DF 0 "register_operand" "=x")
13461         (match_operator:DF 1 "sse_comparison_operator"
13462           [(match_operand:DF 2 "register_operand" "0")
13463            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13464   "TARGET_SSE2"
13465   "cmp%D1sd\t{%3, %0|%0, %3}"
13466   [(set_attr "type" "ssecmp")
13467    (set_attr "mode" "DF")])
13469 ;; Basic conditional jump instructions.
13470 ;; We ignore the overflow flag for signed branch instructions.
13472 ;; For all bCOND expanders, also expand the compare or test insn that
13473 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13475 (define_expand "beq"
13476   [(set (pc)
13477         (if_then_else (match_dup 1)
13478                       (label_ref (match_operand 0 "" ""))
13479                       (pc)))]
13480   ""
13481   "ix86_expand_branch (EQ, operands[0]); DONE;")
13483 (define_expand "bne"
13484   [(set (pc)
13485         (if_then_else (match_dup 1)
13486                       (label_ref (match_operand 0 "" ""))
13487                       (pc)))]
13488   ""
13489   "ix86_expand_branch (NE, operands[0]); DONE;")
13491 (define_expand "bgt"
13492   [(set (pc)
13493         (if_then_else (match_dup 1)
13494                       (label_ref (match_operand 0 "" ""))
13495                       (pc)))]
13496   ""
13497   "ix86_expand_branch (GT, operands[0]); DONE;")
13499 (define_expand "bgtu"
13500   [(set (pc)
13501         (if_then_else (match_dup 1)
13502                       (label_ref (match_operand 0 "" ""))
13503                       (pc)))]
13504   ""
13505   "ix86_expand_branch (GTU, operands[0]); DONE;")
13507 (define_expand "blt"
13508   [(set (pc)
13509         (if_then_else (match_dup 1)
13510                       (label_ref (match_operand 0 "" ""))
13511                       (pc)))]
13512   ""
13513   "ix86_expand_branch (LT, operands[0]); DONE;")
13515 (define_expand "bltu"
13516   [(set (pc)
13517         (if_then_else (match_dup 1)
13518                       (label_ref (match_operand 0 "" ""))
13519                       (pc)))]
13520   ""
13521   "ix86_expand_branch (LTU, operands[0]); DONE;")
13523 (define_expand "bge"
13524   [(set (pc)
13525         (if_then_else (match_dup 1)
13526                       (label_ref (match_operand 0 "" ""))
13527                       (pc)))]
13528   ""
13529   "ix86_expand_branch (GE, operands[0]); DONE;")
13531 (define_expand "bgeu"
13532   [(set (pc)
13533         (if_then_else (match_dup 1)
13534                       (label_ref (match_operand 0 "" ""))
13535                       (pc)))]
13536   ""
13537   "ix86_expand_branch (GEU, operands[0]); DONE;")
13539 (define_expand "ble"
13540   [(set (pc)
13541         (if_then_else (match_dup 1)
13542                       (label_ref (match_operand 0 "" ""))
13543                       (pc)))]
13544   ""
13545   "ix86_expand_branch (LE, operands[0]); DONE;")
13547 (define_expand "bleu"
13548   [(set (pc)
13549         (if_then_else (match_dup 1)
13550                       (label_ref (match_operand 0 "" ""))
13551                       (pc)))]
13552   ""
13553   "ix86_expand_branch (LEU, operands[0]); DONE;")
13555 (define_expand "bunordered"
13556   [(set (pc)
13557         (if_then_else (match_dup 1)
13558                       (label_ref (match_operand 0 "" ""))
13559                       (pc)))]
13560   "TARGET_80387 || TARGET_SSE_MATH"
13561   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13563 (define_expand "bordered"
13564   [(set (pc)
13565         (if_then_else (match_dup 1)
13566                       (label_ref (match_operand 0 "" ""))
13567                       (pc)))]
13568   "TARGET_80387 || TARGET_SSE_MATH"
13569   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13571 (define_expand "buneq"
13572   [(set (pc)
13573         (if_then_else (match_dup 1)
13574                       (label_ref (match_operand 0 "" ""))
13575                       (pc)))]
13576   "TARGET_80387 || TARGET_SSE_MATH"
13577   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13579 (define_expand "bunge"
13580   [(set (pc)
13581         (if_then_else (match_dup 1)
13582                       (label_ref (match_operand 0 "" ""))
13583                       (pc)))]
13584   "TARGET_80387 || TARGET_SSE_MATH"
13585   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13587 (define_expand "bungt"
13588   [(set (pc)
13589         (if_then_else (match_dup 1)
13590                       (label_ref (match_operand 0 "" ""))
13591                       (pc)))]
13592   "TARGET_80387 || TARGET_SSE_MATH"
13593   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13595 (define_expand "bunle"
13596   [(set (pc)
13597         (if_then_else (match_dup 1)
13598                       (label_ref (match_operand 0 "" ""))
13599                       (pc)))]
13600   "TARGET_80387 || TARGET_SSE_MATH"
13601   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13603 (define_expand "bunlt"
13604   [(set (pc)
13605         (if_then_else (match_dup 1)
13606                       (label_ref (match_operand 0 "" ""))
13607                       (pc)))]
13608   "TARGET_80387 || TARGET_SSE_MATH"
13609   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13611 (define_expand "bltgt"
13612   [(set (pc)
13613         (if_then_else (match_dup 1)
13614                       (label_ref (match_operand 0 "" ""))
13615                       (pc)))]
13616   "TARGET_80387 || TARGET_SSE_MATH"
13617   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13619 (define_insn "*jcc_1"
13620   [(set (pc)
13621         (if_then_else (match_operator 1 "ix86_comparison_operator"
13622                                       [(reg FLAGS_REG) (const_int 0)])
13623                       (label_ref (match_operand 0 "" ""))
13624                       (pc)))]
13625   ""
13626   "%+j%C1\t%l0"
13627   [(set_attr "type" "ibr")
13628    (set_attr "modrm" "0")
13629    (set (attr "length")
13630            (if_then_else (and (ge (minus (match_dup 0) (pc))
13631                                   (const_int -126))
13632                               (lt (minus (match_dup 0) (pc))
13633                                   (const_int 128)))
13634              (const_int 2)
13635              (const_int 6)))])
13637 (define_insn "*jcc_2"
13638   [(set (pc)
13639         (if_then_else (match_operator 1 "ix86_comparison_operator"
13640                                       [(reg FLAGS_REG) (const_int 0)])
13641                       (pc)
13642                       (label_ref (match_operand 0 "" ""))))]
13643   ""
13644   "%+j%c1\t%l0"
13645   [(set_attr "type" "ibr")
13646    (set_attr "modrm" "0")
13647    (set (attr "length")
13648            (if_then_else (and (ge (minus (match_dup 0) (pc))
13649                                   (const_int -126))
13650                               (lt (minus (match_dup 0) (pc))
13651                                   (const_int 128)))
13652              (const_int 2)
13653              (const_int 6)))])
13655 ;; In general it is not safe to assume too much about CCmode registers,
13656 ;; so simplify-rtx stops when it sees a second one.  Under certain
13657 ;; conditions this is safe on x86, so help combine not create
13659 ;;      seta    %al
13660 ;;      testb   %al, %al
13661 ;;      je      Lfoo
13663 (define_split
13664   [(set (pc)
13665         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13666                                       [(reg FLAGS_REG) (const_int 0)])
13667                           (const_int 0))
13668                       (label_ref (match_operand 1 "" ""))
13669                       (pc)))]
13670   ""
13671   [(set (pc)
13672         (if_then_else (match_dup 0)
13673                       (label_ref (match_dup 1))
13674                       (pc)))]
13676   PUT_MODE (operands[0], VOIDmode);
13679 (define_split
13680   [(set (pc)
13681         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13682                                       [(reg FLAGS_REG) (const_int 0)])
13683                           (const_int 0))
13684                       (label_ref (match_operand 1 "" ""))
13685                       (pc)))]
13686   ""
13687   [(set (pc)
13688         (if_then_else (match_dup 0)
13689                       (label_ref (match_dup 1))
13690                       (pc)))]
13692   rtx new_op0 = copy_rtx (operands[0]);
13693   operands[0] = new_op0;
13694   PUT_MODE (new_op0, VOIDmode);
13695   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13696                                              GET_MODE (XEXP (new_op0, 0))));
13698   /* Make sure that (a) the CCmode we have for the flags is strong
13699      enough for the reversed compare or (b) we have a valid FP compare.  */
13700   if (! ix86_comparison_operator (new_op0, VOIDmode))
13701     FAIL;
13704 ;; Define combination compare-and-branch fp compare instructions to use
13705 ;; during early optimization.  Splitting the operation apart early makes
13706 ;; for bad code when we want to reverse the operation.
13708 (define_insn "*fp_jcc_1_mixed"
13709   [(set (pc)
13710         (if_then_else (match_operator 0 "comparison_operator"
13711                         [(match_operand 1 "register_operand" "f,x")
13712                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13713           (label_ref (match_operand 3 "" ""))
13714           (pc)))
13715    (clobber (reg:CCFP FPSR_REG))
13716    (clobber (reg:CCFP FLAGS_REG))]
13717   "TARGET_MIX_SSE_I387
13718    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13719    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13720    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13721   "#")
13723 (define_insn "*fp_jcc_1_sse"
13724   [(set (pc)
13725         (if_then_else (match_operator 0 "comparison_operator"
13726                         [(match_operand 1 "register_operand" "x")
13727                          (match_operand 2 "nonimmediate_operand" "xm")])
13728           (label_ref (match_operand 3 "" ""))
13729           (pc)))
13730    (clobber (reg:CCFP FPSR_REG))
13731    (clobber (reg:CCFP FLAGS_REG))]
13732   "TARGET_SSE_MATH
13733    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13734    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13735    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13736   "#")
13738 (define_insn "*fp_jcc_1_387"
13739   [(set (pc)
13740         (if_then_else (match_operator 0 "comparison_operator"
13741                         [(match_operand 1 "register_operand" "f")
13742                          (match_operand 2 "register_operand" "f")])
13743           (label_ref (match_operand 3 "" ""))
13744           (pc)))
13745    (clobber (reg:CCFP FPSR_REG))
13746    (clobber (reg:CCFP FLAGS_REG))]
13747   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13748    && TARGET_CMOVE
13749    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13750    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13751   "#")
13753 (define_insn "*fp_jcc_2_mixed"
13754   [(set (pc)
13755         (if_then_else (match_operator 0 "comparison_operator"
13756                         [(match_operand 1 "register_operand" "f,x")
13757                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13758           (pc)
13759           (label_ref (match_operand 3 "" ""))))
13760    (clobber (reg:CCFP FPSR_REG))
13761    (clobber (reg:CCFP FLAGS_REG))]
13762   "TARGET_MIX_SSE_I387
13763    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13764    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13765    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13766   "#")
13768 (define_insn "*fp_jcc_2_sse"
13769   [(set (pc)
13770         (if_then_else (match_operator 0 "comparison_operator"
13771                         [(match_operand 1 "register_operand" "x")
13772                          (match_operand 2 "nonimmediate_operand" "xm")])
13773           (pc)
13774           (label_ref (match_operand 3 "" ""))))
13775    (clobber (reg:CCFP FPSR_REG))
13776    (clobber (reg:CCFP FLAGS_REG))]
13777   "TARGET_SSE_MATH
13778    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13779    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13780    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13781   "#")
13783 (define_insn "*fp_jcc_2_387"
13784   [(set (pc)
13785         (if_then_else (match_operator 0 "comparison_operator"
13786                         [(match_operand 1 "register_operand" "f")
13787                          (match_operand 2 "register_operand" "f")])
13788           (pc)
13789           (label_ref (match_operand 3 "" ""))))
13790    (clobber (reg:CCFP FPSR_REG))
13791    (clobber (reg:CCFP FLAGS_REG))]
13792   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13793    && TARGET_CMOVE
13794    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13795    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13796   "#")
13798 (define_insn "*fp_jcc_3_387"
13799   [(set (pc)
13800         (if_then_else (match_operator 0 "comparison_operator"
13801                         [(match_operand 1 "register_operand" "f")
13802                          (match_operand 2 "nonimmediate_operand" "fm")])
13803           (label_ref (match_operand 3 "" ""))
13804           (pc)))
13805    (clobber (reg:CCFP FPSR_REG))
13806    (clobber (reg:CCFP FLAGS_REG))
13807    (clobber (match_scratch:HI 4 "=a"))]
13808   "TARGET_80387
13809    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13810    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13811    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13812    && SELECT_CC_MODE (GET_CODE (operands[0]),
13813                       operands[1], operands[2]) == CCFPmode
13814    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13815   "#")
13817 (define_insn "*fp_jcc_4_387"
13818   [(set (pc)
13819         (if_then_else (match_operator 0 "comparison_operator"
13820                         [(match_operand 1 "register_operand" "f")
13821                          (match_operand 2 "nonimmediate_operand" "fm")])
13822           (pc)
13823           (label_ref (match_operand 3 "" ""))))
13824    (clobber (reg:CCFP FPSR_REG))
13825    (clobber (reg:CCFP FLAGS_REG))
13826    (clobber (match_scratch:HI 4 "=a"))]
13827   "TARGET_80387
13828    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13829    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13830    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13831    && SELECT_CC_MODE (GET_CODE (operands[0]),
13832                       operands[1], operands[2]) == CCFPmode
13833    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13834   "#")
13836 (define_insn "*fp_jcc_5_387"
13837   [(set (pc)
13838         (if_then_else (match_operator 0 "comparison_operator"
13839                         [(match_operand 1 "register_operand" "f")
13840                          (match_operand 2 "register_operand" "f")])
13841           (label_ref (match_operand 3 "" ""))
13842           (pc)))
13843    (clobber (reg:CCFP FPSR_REG))
13844    (clobber (reg:CCFP FLAGS_REG))
13845    (clobber (match_scratch:HI 4 "=a"))]
13846   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13847    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13848    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13849   "#")
13851 (define_insn "*fp_jcc_6_387"
13852   [(set (pc)
13853         (if_then_else (match_operator 0 "comparison_operator"
13854                         [(match_operand 1 "register_operand" "f")
13855                          (match_operand 2 "register_operand" "f")])
13856           (pc)
13857           (label_ref (match_operand 3 "" ""))))
13858    (clobber (reg:CCFP FPSR_REG))
13859    (clobber (reg:CCFP FLAGS_REG))
13860    (clobber (match_scratch:HI 4 "=a"))]
13861   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13862    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13863    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13864   "#")
13866 (define_insn "*fp_jcc_7_387"
13867   [(set (pc)
13868         (if_then_else (match_operator 0 "comparison_operator"
13869                         [(match_operand 1 "register_operand" "f")
13870                          (match_operand 2 "const0_operand" "X")])
13871           (label_ref (match_operand 3 "" ""))
13872           (pc)))
13873    (clobber (reg:CCFP FPSR_REG))
13874    (clobber (reg:CCFP FLAGS_REG))
13875    (clobber (match_scratch:HI 4 "=a"))]
13876   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13877    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13878    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13879    && SELECT_CC_MODE (GET_CODE (operands[0]),
13880                       operands[1], operands[2]) == CCFPmode
13881    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13882   "#")
13884 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13885 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13886 ;; with a precedence over other operators and is always put in the first
13887 ;; place. Swap condition and operands to match ficom instruction.
13889 (define_insn "*fp_jcc_8<mode>_387"
13890   [(set (pc)
13891         (if_then_else (match_operator 0 "comparison_operator"
13892                         [(match_operator 1 "float_operator"
13893                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13894                            (match_operand 3 "register_operand" "f,f")])
13895           (label_ref (match_operand 4 "" ""))
13896           (pc)))
13897    (clobber (reg:CCFP FPSR_REG))
13898    (clobber (reg:CCFP FLAGS_REG))
13899    (clobber (match_scratch:HI 5 "=a,a"))]
13900   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13901    && TARGET_USE_<MODE>MODE_FIOP
13902    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13903    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13904    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13905    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13906   "#")
13908 (define_split
13909   [(set (pc)
13910         (if_then_else (match_operator 0 "comparison_operator"
13911                         [(match_operand 1 "register_operand" "")
13912                          (match_operand 2 "nonimmediate_operand" "")])
13913           (match_operand 3 "" "")
13914           (match_operand 4 "" "")))
13915    (clobber (reg:CCFP FPSR_REG))
13916    (clobber (reg:CCFP FLAGS_REG))]
13917   "reload_completed"
13918   [(const_int 0)]
13920   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13921                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13922   DONE;
13925 (define_split
13926   [(set (pc)
13927         (if_then_else (match_operator 0 "comparison_operator"
13928                         [(match_operand 1 "register_operand" "")
13929                          (match_operand 2 "general_operand" "")])
13930           (match_operand 3 "" "")
13931           (match_operand 4 "" "")))
13932    (clobber (reg:CCFP FPSR_REG))
13933    (clobber (reg:CCFP FLAGS_REG))
13934    (clobber (match_scratch:HI 5 "=a"))]
13935   "reload_completed"
13936   [(const_int 0)]
13938   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13939                         operands[3], operands[4], operands[5], NULL_RTX);
13940   DONE;
13943 (define_split
13944   [(set (pc)
13945         (if_then_else (match_operator 0 "comparison_operator"
13946                         [(match_operator 1 "float_operator"
13947                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13948                            (match_operand 3 "register_operand" "")])
13949           (match_operand 4 "" "")
13950           (match_operand 5 "" "")))
13951    (clobber (reg:CCFP FPSR_REG))
13952    (clobber (reg:CCFP FLAGS_REG))
13953    (clobber (match_scratch:HI 6 "=a"))]
13954   "reload_completed"
13955   [(const_int 0)]
13957   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13958   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13959                         operands[3], operands[7],
13960                         operands[4], operands[5], operands[6], NULL_RTX);
13961   DONE;
13964 ;; %%% Kill this when reload knows how to do it.
13965 (define_split
13966   [(set (pc)
13967         (if_then_else (match_operator 0 "comparison_operator"
13968                         [(match_operator 1 "float_operator"
13969                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13970                            (match_operand 3 "register_operand" "")])
13971           (match_operand 4 "" "")
13972           (match_operand 5 "" "")))
13973    (clobber (reg:CCFP FPSR_REG))
13974    (clobber (reg:CCFP FLAGS_REG))
13975    (clobber (match_scratch:HI 6 "=a"))]
13976   "reload_completed"
13977   [(const_int 0)]
13979   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13980   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13981   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13982                         operands[3], operands[7],
13983                         operands[4], operands[5], operands[6], operands[2]);
13984   DONE;
13987 ;; Unconditional and other jump instructions
13989 (define_insn "jump"
13990   [(set (pc)
13991         (label_ref (match_operand 0 "" "")))]
13992   ""
13993   "jmp\t%l0"
13994   [(set_attr "type" "ibr")
13995    (set (attr "length")
13996            (if_then_else (and (ge (minus (match_dup 0) (pc))
13997                                   (const_int -126))
13998                               (lt (minus (match_dup 0) (pc))
13999                                   (const_int 128)))
14000              (const_int 2)
14001              (const_int 5)))
14002    (set_attr "modrm" "0")])
14004 (define_expand "indirect_jump"
14005   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14006   ""
14007   "")
14009 (define_insn "*indirect_jump"
14010   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14011   "!TARGET_64BIT"
14012   "jmp\t%A0"
14013   [(set_attr "type" "ibr")
14014    (set_attr "length_immediate" "0")])
14016 (define_insn "*indirect_jump_rtx64"
14017   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14018   "TARGET_64BIT"
14019   "jmp\t%A0"
14020   [(set_attr "type" "ibr")
14021    (set_attr "length_immediate" "0")])
14023 (define_expand "tablejump"
14024   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14025               (use (label_ref (match_operand 1 "" "")))])]
14026   ""
14028   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14029      relative.  Convert the relative address to an absolute address.  */
14030   if (flag_pic)
14031     {
14032       rtx op0, op1;
14033       enum rtx_code code;
14035       /* We can't use @GOTOFF for text labels on VxWorks;
14036          see gotoff_operand.  */
14037       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14038         {
14039           code = PLUS;
14040           op0 = operands[0];
14041           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14042         }
14043       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14044         {
14045           code = PLUS;
14046           op0 = operands[0];
14047           op1 = pic_offset_table_rtx;
14048         }
14049       else
14050         {
14051           code = MINUS;
14052           op0 = pic_offset_table_rtx;
14053           op1 = operands[0];
14054         }
14056       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14057                                          OPTAB_DIRECT);
14058     }
14061 (define_insn "*tablejump_1"
14062   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14063    (use (label_ref (match_operand 1 "" "")))]
14064   "!TARGET_64BIT"
14065   "jmp\t%A0"
14066   [(set_attr "type" "ibr")
14067    (set_attr "length_immediate" "0")])
14069 (define_insn "*tablejump_1_rtx64"
14070   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14071    (use (label_ref (match_operand 1 "" "")))]
14072   "TARGET_64BIT"
14073   "jmp\t%A0"
14074   [(set_attr "type" "ibr")
14075    (set_attr "length_immediate" "0")])
14077 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14079 (define_peephole2
14080   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14081    (set (match_operand:QI 1 "register_operand" "")
14082         (match_operator:QI 2 "ix86_comparison_operator"
14083           [(reg FLAGS_REG) (const_int 0)]))
14084    (set (match_operand 3 "q_regs_operand" "")
14085         (zero_extend (match_dup 1)))]
14086   "(peep2_reg_dead_p (3, operands[1])
14087     || operands_match_p (operands[1], operands[3]))
14088    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14089   [(set (match_dup 4) (match_dup 0))
14090    (set (strict_low_part (match_dup 5))
14091         (match_dup 2))]
14093   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14094   operands[5] = gen_lowpart (QImode, operands[3]);
14095   ix86_expand_clear (operands[3]);
14098 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14100 (define_peephole2
14101   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14102    (set (match_operand:QI 1 "register_operand" "")
14103         (match_operator:QI 2 "ix86_comparison_operator"
14104           [(reg FLAGS_REG) (const_int 0)]))
14105    (parallel [(set (match_operand 3 "q_regs_operand" "")
14106                    (zero_extend (match_dup 1)))
14107               (clobber (reg:CC FLAGS_REG))])]
14108   "(peep2_reg_dead_p (3, operands[1])
14109     || operands_match_p (operands[1], operands[3]))
14110    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14111   [(set (match_dup 4) (match_dup 0))
14112    (set (strict_low_part (match_dup 5))
14113         (match_dup 2))]
14115   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14116   operands[5] = gen_lowpart (QImode, operands[3]);
14117   ix86_expand_clear (operands[3]);
14120 ;; Call instructions.
14122 ;; The predicates normally associated with named expanders are not properly
14123 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14124 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14126 ;; Call subroutine returning no value.
14128 (define_expand "call_pop"
14129   [(parallel [(call (match_operand:QI 0 "" "")
14130                     (match_operand:SI 1 "" ""))
14131               (set (reg:SI SP_REG)
14132                    (plus:SI (reg:SI SP_REG)
14133                             (match_operand:SI 3 "" "")))])]
14134   "!TARGET_64BIT"
14136   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14137   DONE;
14140 (define_insn "*call_pop_0"
14141   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14142          (match_operand:SI 1 "" ""))
14143    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14144                             (match_operand:SI 2 "immediate_operand" "")))]
14145   "!TARGET_64BIT"
14147   if (SIBLING_CALL_P (insn))
14148     return "jmp\t%P0";
14149   else
14150     return "call\t%P0";
14152   [(set_attr "type" "call")])
14154 (define_insn "*call_pop_1"
14155   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14156          (match_operand:SI 1 "" ""))
14157    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14158                             (match_operand:SI 2 "immediate_operand" "i")))]
14159   "!TARGET_64BIT"
14161   if (constant_call_address_operand (operands[0], Pmode))
14162     {
14163       if (SIBLING_CALL_P (insn))
14164         return "jmp\t%P0";
14165       else
14166         return "call\t%P0";
14167     }
14168   if (SIBLING_CALL_P (insn))
14169     return "jmp\t%A0";
14170   else
14171     return "call\t%A0";
14173   [(set_attr "type" "call")])
14175 (define_expand "call"
14176   [(call (match_operand:QI 0 "" "")
14177          (match_operand 1 "" ""))
14178    (use (match_operand 2 "" ""))]
14179   ""
14181   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14182   DONE;
14185 (define_expand "sibcall"
14186   [(call (match_operand:QI 0 "" "")
14187          (match_operand 1 "" ""))
14188    (use (match_operand 2 "" ""))]
14189   ""
14191   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14192   DONE;
14195 (define_insn "*call_0"
14196   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14197          (match_operand 1 "" ""))]
14198   ""
14200   if (SIBLING_CALL_P (insn))
14201     return "jmp\t%P0";
14202   else
14203     return "call\t%P0";
14205   [(set_attr "type" "call")])
14207 (define_insn "*call_1"
14208   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14209          (match_operand 1 "" ""))]
14210   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14212   if (constant_call_address_operand (operands[0], Pmode))
14213     return "call\t%P0";
14214   return "call\t%A0";
14216   [(set_attr "type" "call")])
14218 (define_insn "*sibcall_1"
14219   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14220          (match_operand 1 "" ""))]
14221   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14223   if (constant_call_address_operand (operands[0], Pmode))
14224     return "jmp\t%P0";
14225   return "jmp\t%A0";
14227   [(set_attr "type" "call")])
14229 (define_insn "*call_1_rex64"
14230   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14231          (match_operand 1 "" ""))]
14232   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14233    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14235   if (constant_call_address_operand (operands[0], Pmode))
14236     return "call\t%P0";
14237   return "call\t%A0";
14239   [(set_attr "type" "call")])
14241 (define_insn "*call_1_rex64_large"
14242   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14243          (match_operand 1 "" ""))]
14244   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14245   "call\t%A0"
14246   [(set_attr "type" "call")])
14248 (define_insn "*sibcall_1_rex64"
14249   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14250          (match_operand 1 "" ""))]
14251   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14252   "jmp\t%P0"
14253   [(set_attr "type" "call")])
14255 (define_insn "*sibcall_1_rex64_v"
14256   [(call (mem:QI (reg:DI R11_REG))
14257          (match_operand 0 "" ""))]
14258   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14259   "jmp\t*%%r11"
14260   [(set_attr "type" "call")])
14263 ;; Call subroutine, returning value in operand 0
14265 (define_expand "call_value_pop"
14266   [(parallel [(set (match_operand 0 "" "")
14267                    (call (match_operand:QI 1 "" "")
14268                          (match_operand:SI 2 "" "")))
14269               (set (reg:SI SP_REG)
14270                    (plus:SI (reg:SI SP_REG)
14271                             (match_operand:SI 4 "" "")))])]
14272   "!TARGET_64BIT"
14274   ix86_expand_call (operands[0], operands[1], operands[2],
14275                     operands[3], operands[4], 0);
14276   DONE;
14279 (define_expand "call_value"
14280   [(set (match_operand 0 "" "")
14281         (call (match_operand:QI 1 "" "")
14282               (match_operand:SI 2 "" "")))
14283    (use (match_operand:SI 3 "" ""))]
14284   ;; Operand 2 not used on the i386.
14285   ""
14287   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14288   DONE;
14291 (define_expand "sibcall_value"
14292   [(set (match_operand 0 "" "")
14293         (call (match_operand:QI 1 "" "")
14294               (match_operand:SI 2 "" "")))
14295    (use (match_operand:SI 3 "" ""))]
14296   ;; Operand 2 not used on the i386.
14297   ""
14299   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14300   DONE;
14303 ;; Call subroutine returning any type.
14305 (define_expand "untyped_call"
14306   [(parallel [(call (match_operand 0 "" "")
14307                     (const_int 0))
14308               (match_operand 1 "" "")
14309               (match_operand 2 "" "")])]
14310   ""
14312   int i;
14314   /* In order to give reg-stack an easier job in validating two
14315      coprocessor registers as containing a possible return value,
14316      simply pretend the untyped call returns a complex long double
14317      value.  */
14319   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14320                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14321                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14322                     NULL, 0);
14324   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14325     {
14326       rtx set = XVECEXP (operands[2], 0, i);
14327       emit_move_insn (SET_DEST (set), SET_SRC (set));
14328     }
14330   /* The optimizer does not know that the call sets the function value
14331      registers we stored in the result block.  We avoid problems by
14332      claiming that all hard registers are used and clobbered at this
14333      point.  */
14334   emit_insn (gen_blockage (const0_rtx));
14336   DONE;
14339 ;; Prologue and epilogue instructions
14341 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14342 ;; all of memory.  This blocks insns from being moved across this point.
14344 (define_insn "blockage"
14345   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14346   ""
14347   ""
14348   [(set_attr "length" "0")])
14350 ;; Insn emitted into the body of a function to return from a function.
14351 ;; This is only done if the function's epilogue is known to be simple.
14352 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14354 (define_expand "return"
14355   [(return)]
14356   "ix86_can_use_return_insn_p ()"
14358   if (current_function_pops_args)
14359     {
14360       rtx popc = GEN_INT (current_function_pops_args);
14361       emit_jump_insn (gen_return_pop_internal (popc));
14362       DONE;
14363     }
14366 (define_insn "return_internal"
14367   [(return)]
14368   "reload_completed"
14369   "ret"
14370   [(set_attr "length" "1")
14371    (set_attr "length_immediate" "0")
14372    (set_attr "modrm" "0")])
14374 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14375 ;; instruction Athlon and K8 have.
14377 (define_insn "return_internal_long"
14378   [(return)
14379    (unspec [(const_int 0)] UNSPEC_REP)]
14380   "reload_completed"
14381   "rep {;} ret"
14382   [(set_attr "length" "1")
14383    (set_attr "length_immediate" "0")
14384    (set_attr "prefix_rep" "1")
14385    (set_attr "modrm" "0")])
14387 (define_insn "return_pop_internal"
14388   [(return)
14389    (use (match_operand:SI 0 "const_int_operand" ""))]
14390   "reload_completed"
14391   "ret\t%0"
14392   [(set_attr "length" "3")
14393    (set_attr "length_immediate" "2")
14394    (set_attr "modrm" "0")])
14396 (define_insn "return_indirect_internal"
14397   [(return)
14398    (use (match_operand:SI 0 "register_operand" "r"))]
14399   "reload_completed"
14400   "jmp\t%A0"
14401   [(set_attr "type" "ibr")
14402    (set_attr "length_immediate" "0")])
14404 (define_insn "nop"
14405   [(const_int 0)]
14406   ""
14407   "nop"
14408   [(set_attr "length" "1")
14409    (set_attr "length_immediate" "0")
14410    (set_attr "modrm" "0")])
14412 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14413 ;; branch prediction penalty for the third jump in a 16-byte
14414 ;; block on K8.
14416 (define_insn "align"
14417   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14418   ""
14420 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14421   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14422 #else
14423   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14424      The align insn is used to avoid 3 jump instructions in the row to improve
14425      branch prediction and the benefits hardly outweigh the cost of extra 8
14426      nops on the average inserted by full alignment pseudo operation.  */
14427 #endif
14428   return "";
14430   [(set_attr "length" "16")])
14432 (define_expand "prologue"
14433   [(const_int 1)]
14434   ""
14435   "ix86_expand_prologue (); DONE;")
14437 (define_insn "set_got"
14438   [(set (match_operand:SI 0 "register_operand" "=r")
14439         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14440    (clobber (reg:CC FLAGS_REG))]
14441   "!TARGET_64BIT"
14442   { return output_set_got (operands[0], NULL_RTX); }
14443   [(set_attr "type" "multi")
14444    (set_attr "length" "12")])
14446 (define_insn "set_got_labelled"
14447   [(set (match_operand:SI 0 "register_operand" "=r")
14448         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14449          UNSPEC_SET_GOT))
14450    (clobber (reg:CC FLAGS_REG))]
14451   "!TARGET_64BIT"
14452   { return output_set_got (operands[0], operands[1]); }
14453   [(set_attr "type" "multi")
14454    (set_attr "length" "12")])
14456 (define_insn "set_got_rex64"
14457   [(set (match_operand:DI 0 "register_operand" "=r")
14458         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14459   "TARGET_64BIT"
14460   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14461   [(set_attr "type" "lea")
14462    (set_attr "length" "6")])
14464 (define_insn "set_rip_rex64"
14465   [(set (match_operand:DI 0 "register_operand" "=r")
14466         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14467   "TARGET_64BIT"
14468   "lea{q}\t%l1(%%rip), %0"
14469   [(set_attr "type" "lea")
14470    (set_attr "length" "6")])
14472 (define_insn "set_got_offset_rex64"
14473   [(set (match_operand:DI 0 "register_operand" "=r")
14474         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14475   "TARGET_64BIT"
14476   "movabs{q}\t$_GLOBAL_OFFSET_TABLE_-%l1, %0"
14477   [(set_attr "type" "imov")
14478    (set_attr "length" "11")])
14480 (define_expand "epilogue"
14481   [(const_int 1)]
14482   ""
14483   "ix86_expand_epilogue (1); DONE;")
14485 (define_expand "sibcall_epilogue"
14486   [(const_int 1)]
14487   ""
14488   "ix86_expand_epilogue (0); DONE;")
14490 (define_expand "eh_return"
14491   [(use (match_operand 0 "register_operand" ""))]
14492   ""
14494   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14496   /* Tricky bit: we write the address of the handler to which we will
14497      be returning into someone else's stack frame, one word below the
14498      stack address we wish to restore.  */
14499   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14500   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14501   tmp = gen_rtx_MEM (Pmode, tmp);
14502   emit_move_insn (tmp, ra);
14504   if (Pmode == SImode)
14505     emit_jump_insn (gen_eh_return_si (sa));
14506   else
14507     emit_jump_insn (gen_eh_return_di (sa));
14508   emit_barrier ();
14509   DONE;
14512 (define_insn_and_split "eh_return_si"
14513   [(set (pc)
14514         (unspec [(match_operand:SI 0 "register_operand" "c")]
14515                  UNSPEC_EH_RETURN))]
14516   "!TARGET_64BIT"
14517   "#"
14518   "reload_completed"
14519   [(const_int 1)]
14520   "ix86_expand_epilogue (2); DONE;")
14522 (define_insn_and_split "eh_return_di"
14523   [(set (pc)
14524         (unspec [(match_operand:DI 0 "register_operand" "c")]
14525                  UNSPEC_EH_RETURN))]
14526   "TARGET_64BIT"
14527   "#"
14528   "reload_completed"
14529   [(const_int 1)]
14530   "ix86_expand_epilogue (2); DONE;")
14532 (define_insn "leave"
14533   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14534    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14535    (clobber (mem:BLK (scratch)))]
14536   "!TARGET_64BIT"
14537   "leave"
14538   [(set_attr "type" "leave")])
14540 (define_insn "leave_rex64"
14541   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14542    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14543    (clobber (mem:BLK (scratch)))]
14544   "TARGET_64BIT"
14545   "leave"
14546   [(set_attr "type" "leave")])
14548 (define_expand "ffssi2"
14549   [(parallel
14550      [(set (match_operand:SI 0 "register_operand" "")
14551            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14552       (clobber (match_scratch:SI 2 ""))
14553       (clobber (reg:CC FLAGS_REG))])]
14554   ""
14555   "")
14557 (define_insn_and_split "*ffs_cmove"
14558   [(set (match_operand:SI 0 "register_operand" "=r")
14559         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14560    (clobber (match_scratch:SI 2 "=&r"))
14561    (clobber (reg:CC FLAGS_REG))]
14562   "TARGET_CMOVE"
14563   "#"
14564   "&& reload_completed"
14565   [(set (match_dup 2) (const_int -1))
14566    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14567               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14568    (set (match_dup 0) (if_then_else:SI
14569                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14570                         (match_dup 2)
14571                         (match_dup 0)))
14572    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14573               (clobber (reg:CC FLAGS_REG))])]
14574   "")
14576 (define_insn_and_split "*ffs_no_cmove"
14577   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14578         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14579    (clobber (match_scratch:SI 2 "=&q"))
14580    (clobber (reg:CC FLAGS_REG))]
14581   ""
14582   "#"
14583   "reload_completed"
14584   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14585               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14586    (set (strict_low_part (match_dup 3))
14587         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14588    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14589               (clobber (reg:CC FLAGS_REG))])
14590    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14591               (clobber (reg:CC FLAGS_REG))])
14592    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14593               (clobber (reg:CC FLAGS_REG))])]
14595   operands[3] = gen_lowpart (QImode, operands[2]);
14596   ix86_expand_clear (operands[2]);
14599 (define_insn "*ffssi_1"
14600   [(set (reg:CCZ FLAGS_REG)
14601         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14602                      (const_int 0)))
14603    (set (match_operand:SI 0 "register_operand" "=r")
14604         (ctz:SI (match_dup 1)))]
14605   ""
14606   "bsf{l}\t{%1, %0|%0, %1}"
14607   [(set_attr "prefix_0f" "1")])
14609 (define_expand "ffsdi2"
14610   [(parallel
14611      [(set (match_operand:DI 0 "register_operand" "")
14612            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14613       (clobber (match_scratch:DI 2 ""))
14614       (clobber (reg:CC FLAGS_REG))])]
14615   "TARGET_64BIT && TARGET_CMOVE"
14616   "")
14618 (define_insn_and_split "*ffs_rex64"
14619   [(set (match_operand:DI 0 "register_operand" "=r")
14620         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14621    (clobber (match_scratch:DI 2 "=&r"))
14622    (clobber (reg:CC FLAGS_REG))]
14623   "TARGET_64BIT && TARGET_CMOVE"
14624   "#"
14625   "&& reload_completed"
14626   [(set (match_dup 2) (const_int -1))
14627    (parallel [(set (reg:CCZ FLAGS_REG)
14628                    (compare:CCZ (match_dup 1) (const_int 0)))
14629               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14630    (set (match_dup 0) (if_then_else:DI
14631                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14632                         (match_dup 2)
14633                         (match_dup 0)))
14634    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14635               (clobber (reg:CC FLAGS_REG))])]
14636   "")
14638 (define_insn "*ffsdi_1"
14639   [(set (reg:CCZ FLAGS_REG)
14640         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14641                      (const_int 0)))
14642    (set (match_operand:DI 0 "register_operand" "=r")
14643         (ctz:DI (match_dup 1)))]
14644   "TARGET_64BIT"
14645   "bsf{q}\t{%1, %0|%0, %1}"
14646   [(set_attr "prefix_0f" "1")])
14648 (define_insn "ctzsi2"
14649   [(set (match_operand:SI 0 "register_operand" "=r")
14650         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14651    (clobber (reg:CC FLAGS_REG))]
14652   ""
14653   "bsf{l}\t{%1, %0|%0, %1}"
14654   [(set_attr "prefix_0f" "1")])
14656 (define_insn "ctzdi2"
14657   [(set (match_operand:DI 0 "register_operand" "=r")
14658         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14659    (clobber (reg:CC FLAGS_REG))]
14660   "TARGET_64BIT"
14661   "bsf{q}\t{%1, %0|%0, %1}"
14662   [(set_attr "prefix_0f" "1")])
14664 (define_expand "clzsi2"
14665   [(parallel
14666      [(set (match_operand:SI 0 "register_operand" "")
14667            (minus:SI (const_int 31)
14668                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14669       (clobber (reg:CC FLAGS_REG))])
14670    (parallel
14671      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14672       (clobber (reg:CC FLAGS_REG))])]
14673   ""
14675   if (TARGET_ABM)
14676     {
14677       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14678       DONE;
14679     }
14682 (define_insn "clzsi2_abm"
14683   [(set (match_operand:SI 0 "register_operand" "=r")
14684         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14685    (clobber (reg:CC FLAGS_REG))]
14686   "TARGET_ABM"
14687   "lzcnt{l}\t{%1, %0|%0, %1}"
14688   [(set_attr "prefix_rep" "1")
14689    (set_attr "type" "bitmanip")
14690    (set_attr "mode" "SI")])
14692 (define_insn "*bsr"
14693   [(set (match_operand:SI 0 "register_operand" "=r")
14694         (minus:SI (const_int 31)
14695                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14696    (clobber (reg:CC FLAGS_REG))]
14697   ""
14698   "bsr{l}\t{%1, %0|%0, %1}"
14699   [(set_attr "prefix_0f" "1")
14700    (set_attr "mode" "SI")])
14702 (define_insn "popcountsi2"
14703   [(set (match_operand:SI 0 "register_operand" "=r")
14704         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14705    (clobber (reg:CC FLAGS_REG))]
14706   "TARGET_POPCNT"
14707   "popcnt{l}\t{%1, %0|%0, %1}"
14708   [(set_attr "prefix_rep" "1")
14709    (set_attr "type" "bitmanip")
14710    (set_attr "mode" "SI")])
14712 (define_insn "*popcountsi2_cmp"
14713   [(set (reg FLAGS_REG)
14714         (compare
14715           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14716           (const_int 0)))
14717    (set (match_operand:SI 0 "register_operand" "=r")
14718         (popcount:SI (match_dup 1)))]
14719   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14720   "popcnt{l}\t{%1, %0|%0, %1}"
14721   [(set_attr "prefix_rep" "1")
14722    (set_attr "type" "bitmanip")
14723    (set_attr "mode" "SI")])
14725 (define_insn "*popcountsi2_cmp_zext"
14726   [(set (reg FLAGS_REG)
14727         (compare
14728           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14729           (const_int 0)))
14730    (set (match_operand:DI 0 "register_operand" "=r")
14731         (zero_extend:DI(popcount:SI (match_dup 1))))]
14732   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14733   "popcnt{l}\t{%1, %0|%0, %1}"
14734   [(set_attr "prefix_rep" "1")
14735    (set_attr "type" "bitmanip")
14736    (set_attr "mode" "SI")])
14738 (define_expand "bswapsi2"
14739   [(set (match_operand:SI 0 "register_operand" "")
14740         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14741   ""
14743   if (!TARGET_BSWAP)
14744     {
14745       rtx x = operands[0];
14747       emit_move_insn (x, operands[1]);
14748       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14749       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14750       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14751       DONE;
14752     }
14755 (define_insn "*bswapsi_1"
14756   [(set (match_operand:SI 0 "register_operand" "=r")
14757         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14758   "TARGET_BSWAP"
14759   "bswap\t%0"
14760   [(set_attr "prefix_0f" "1")
14761    (set_attr "length" "2")])
14763 (define_insn "*bswaphi_lowpart_1"
14764   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14765         (bswap:HI (match_dup 0)))
14766    (clobber (reg:CC FLAGS_REG))]
14767   "TARGET_USE_XCHGB || optimize_size"
14768   "@
14769     xchg{b}\t{%h0, %b0|%b0, %h0}
14770     rol{w}\t{$8, %0|%0, 8}"
14771   [(set_attr "length" "2,4")
14772    (set_attr "mode" "QI,HI")])
14774 (define_insn "bswaphi_lowpart"
14775   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14776         (bswap:HI (match_dup 0)))
14777    (clobber (reg:CC FLAGS_REG))]
14778   ""
14779   "rol{w}\t{$8, %0|%0, 8}"
14780   [(set_attr "length" "4")
14781    (set_attr "mode" "HI")])
14783 (define_insn "bswapdi2"
14784   [(set (match_operand:DI 0 "register_operand" "=r")
14785         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14786   "TARGET_64BIT"
14787   "bswap\t%0"
14788   [(set_attr "prefix_0f" "1")
14789    (set_attr "length" "3")])
14791 (define_expand "clzdi2"
14792   [(parallel
14793      [(set (match_operand:DI 0 "register_operand" "")
14794            (minus:DI (const_int 63)
14795                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14796       (clobber (reg:CC FLAGS_REG))])
14797    (parallel
14798      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14799       (clobber (reg:CC FLAGS_REG))])]
14800   "TARGET_64BIT"
14802   if (TARGET_ABM)
14803     {
14804       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14805       DONE;
14806     }
14809 (define_insn "clzdi2_abm"
14810   [(set (match_operand:DI 0 "register_operand" "=r")
14811         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14812    (clobber (reg:CC FLAGS_REG))]
14813   "TARGET_64BIT && TARGET_ABM"
14814   "lzcnt{q}\t{%1, %0|%0, %1}"
14815   [(set_attr "prefix_rep" "1")
14816    (set_attr "type" "bitmanip")
14817    (set_attr "mode" "DI")])
14819 (define_insn "*bsr_rex64"
14820   [(set (match_operand:DI 0 "register_operand" "=r")
14821         (minus:DI (const_int 63)
14822                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14823    (clobber (reg:CC FLAGS_REG))]
14824   "TARGET_64BIT"
14825   "bsr{q}\t{%1, %0|%0, %1}"
14826   [(set_attr "prefix_0f" "1")
14827    (set_attr "mode" "DI")])
14829 (define_insn "popcountdi2"
14830   [(set (match_operand:DI 0 "register_operand" "=r")
14831         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14832    (clobber (reg:CC FLAGS_REG))]
14833   "TARGET_64BIT && TARGET_POPCNT"
14834   "popcnt{q}\t{%1, %0|%0, %1}"
14835   [(set_attr "prefix_rep" "1")
14836    (set_attr "type" "bitmanip")
14837    (set_attr "mode" "DI")])
14839 (define_insn "*popcountdi2_cmp"
14840   [(set (reg FLAGS_REG)
14841         (compare
14842           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14843           (const_int 0)))
14844    (set (match_operand:DI 0 "register_operand" "=r")
14845         (popcount:DI (match_dup 1)))]
14846   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14847   "popcnt{q}\t{%1, %0|%0, %1}"
14848   [(set_attr "prefix_rep" "1")
14849    (set_attr "type" "bitmanip")
14850    (set_attr "mode" "DI")])
14852 (define_expand "clzhi2"
14853   [(parallel
14854      [(set (match_operand:HI 0 "register_operand" "")
14855            (minus:HI (const_int 15)
14856                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14857       (clobber (reg:CC FLAGS_REG))])
14858    (parallel
14859      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14860       (clobber (reg:CC FLAGS_REG))])]
14861   ""
14863   if (TARGET_ABM)
14864     {
14865       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14866       DONE;
14867     }
14870 (define_insn "clzhi2_abm"
14871   [(set (match_operand:HI 0 "register_operand" "=r")
14872         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14873    (clobber (reg:CC FLAGS_REG))]
14874   "TARGET_ABM"
14875   "lzcnt{w}\t{%1, %0|%0, %1}"
14876   [(set_attr "prefix_rep" "1")
14877    (set_attr "type" "bitmanip")
14878    (set_attr "mode" "HI")])
14880 (define_insn "*bsrhi"
14881   [(set (match_operand:HI 0 "register_operand" "=r")
14882         (minus:HI (const_int 15)
14883                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14884    (clobber (reg:CC FLAGS_REG))]
14885   ""
14886   "bsr{w}\t{%1, %0|%0, %1}"
14887   [(set_attr "prefix_0f" "1")
14888    (set_attr "mode" "HI")])
14890 (define_insn "popcounthi2"
14891   [(set (match_operand:HI 0 "register_operand" "=r")
14892         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14893    (clobber (reg:CC FLAGS_REG))]
14894   "TARGET_POPCNT"
14895   "popcnt{w}\t{%1, %0|%0, %1}"
14896   [(set_attr "prefix_rep" "1")
14897    (set_attr "type" "bitmanip")
14898    (set_attr "mode" "HI")])
14900 (define_insn "*popcounthi2_cmp"
14901   [(set (reg FLAGS_REG)
14902         (compare
14903           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14904           (const_int 0)))
14905    (set (match_operand:HI 0 "register_operand" "=r")
14906         (popcount:HI (match_dup 1)))]
14907   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14908   "popcnt{w}\t{%1, %0|%0, %1}"
14909   [(set_attr "prefix_rep" "1")
14910    (set_attr "type" "bitmanip")
14911    (set_attr "mode" "HI")])
14913 (define_expand "paritydi2"
14914   [(set (match_operand:DI 0 "register_operand" "")
14915         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
14916   "! TARGET_POPCNT"
14918   rtx scratch = gen_reg_rtx (QImode);
14919   rtx cond;
14921   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14922                                 NULL_RTX, operands[1]));
14924   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14925                          gen_rtx_REG (CCmode, FLAGS_REG),
14926                          const0_rtx);
14927   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14929   if (TARGET_64BIT)
14930     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14931   else
14932     {
14933       rtx tmp = gen_reg_rtx (SImode);
14935       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14936       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14937     }
14938   DONE;
14941 (define_insn_and_split "paritydi2_cmp"
14942   [(set (reg:CC FLAGS_REG)
14943         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
14944    (clobber (match_scratch:DI 0 "=r,X"))
14945    (clobber (match_scratch:SI 1 "=r,r"))
14946    (clobber (match_scratch:HI 2 "=Q,Q"))]
14947   "! TARGET_POPCNT"
14948   "#"
14949   "&& reload_completed"
14950   [(parallel
14951      [(set (match_dup 1)
14952            (xor:SI (match_dup 1) (match_dup 4)))
14953       (clobber (reg:CC FLAGS_REG))])
14954    (parallel
14955      [(set (reg:CC FLAGS_REG)
14956            (parity:CC (match_dup 1)))
14957       (clobber (match_dup 1))
14958       (clobber (match_dup 2))])]
14960   operands[4] = gen_lowpart (SImode, operands[3]);
14962   if (MEM_P (operands[3]))
14963     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
14964   else if (! TARGET_64BIT)
14965     operands[1] = gen_highpart (SImode, operands[3]);
14966   else
14967     {
14968       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14969       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14970     }
14973 (define_expand "paritysi2"
14974   [(set (match_operand:SI 0 "register_operand" "")
14975         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
14976   "! TARGET_POPCNT"
14978   rtx scratch = gen_reg_rtx (QImode);
14979   rtx cond;
14981   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14983   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14984                          gen_rtx_REG (CCmode, FLAGS_REG),
14985                          const0_rtx);
14986   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14988   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14989   DONE;
14992 (define_insn_and_split "paritysi2_cmp"
14993   [(set (reg:CC FLAGS_REG)
14994         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
14995    (clobber (match_scratch:SI 0 "=r,X"))
14996    (clobber (match_scratch:HI 1 "=Q,Q"))]
14997   "! TARGET_POPCNT"
14998   "#"
14999   "&& reload_completed"
15000   [(parallel
15001      [(set (match_dup 1)
15002            (xor:HI (match_dup 1) (match_dup 3)))
15003       (clobber (reg:CC FLAGS_REG))])
15004    (parallel
15005      [(set (reg:CC FLAGS_REG)
15006            (parity:CC (match_dup 1)))
15007       (clobber (match_dup 1))])]
15009   operands[3] = gen_lowpart (HImode, operands[2]);
15011   if (MEM_P (operands[2]))
15012     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15013   else
15014     {
15015       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15016       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15017     }
15020 (define_insn "*parityhi2_cmp"
15021   [(set (reg:CC FLAGS_REG)
15022         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15023    (clobber (match_scratch:HI 0 "=Q"))]
15024   "! TARGET_POPCNT"
15025   "xor{b}\t{%h0, %b0|%b0, %h0}"
15026   [(set_attr "length" "2")
15027    (set_attr "mode" "HI")])
15029 (define_insn "*parityqi2_cmp"
15030   [(set (reg:CC FLAGS_REG)
15031         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15032   "! TARGET_POPCNT"
15033   "test{b}\t%0, %0"
15034   [(set_attr "length" "2")
15035    (set_attr "mode" "QI")])
15037 ;; Thread-local storage patterns for ELF.
15039 ;; Note that these code sequences must appear exactly as shown
15040 ;; in order to allow linker relaxation.
15042 (define_insn "*tls_global_dynamic_32_gnu"
15043   [(set (match_operand:SI 0 "register_operand" "=a")
15044         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15045                     (match_operand:SI 2 "tls_symbolic_operand" "")
15046                     (match_operand:SI 3 "call_insn_operand" "")]
15047                     UNSPEC_TLS_GD))
15048    (clobber (match_scratch:SI 4 "=d"))
15049    (clobber (match_scratch:SI 5 "=c"))
15050    (clobber (reg:CC FLAGS_REG))]
15051   "!TARGET_64BIT && TARGET_GNU_TLS"
15052   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15053   [(set_attr "type" "multi")
15054    (set_attr "length" "12")])
15056 (define_insn "*tls_global_dynamic_32_sun"
15057   [(set (match_operand:SI 0 "register_operand" "=a")
15058         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15059                     (match_operand:SI 2 "tls_symbolic_operand" "")
15060                     (match_operand:SI 3 "call_insn_operand" "")]
15061                     UNSPEC_TLS_GD))
15062    (clobber (match_scratch:SI 4 "=d"))
15063    (clobber (match_scratch:SI 5 "=c"))
15064    (clobber (reg:CC FLAGS_REG))]
15065   "!TARGET_64BIT && TARGET_SUN_TLS"
15066   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15067         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15068   [(set_attr "type" "multi")
15069    (set_attr "length" "14")])
15071 (define_expand "tls_global_dynamic_32"
15072   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15073                    (unspec:SI
15074                     [(match_dup 2)
15075                      (match_operand:SI 1 "tls_symbolic_operand" "")
15076                      (match_dup 3)]
15077                     UNSPEC_TLS_GD))
15078               (clobber (match_scratch:SI 4 ""))
15079               (clobber (match_scratch:SI 5 ""))
15080               (clobber (reg:CC FLAGS_REG))])]
15081   ""
15083   if (flag_pic)
15084     operands[2] = pic_offset_table_rtx;
15085   else
15086     {
15087       operands[2] = gen_reg_rtx (Pmode);
15088       emit_insn (gen_set_got (operands[2]));
15089     }
15090   if (TARGET_GNU2_TLS)
15091     {
15092        emit_insn (gen_tls_dynamic_gnu2_32
15093                   (operands[0], operands[1], operands[2]));
15094        DONE;
15095     }
15096   operands[3] = ix86_tls_get_addr ();
15099 (define_insn "*tls_global_dynamic_64"
15100   [(set (match_operand:DI 0 "register_operand" "=a")
15101         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15102                  (match_operand:DI 3 "" "")))
15103    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15104               UNSPEC_TLS_GD)]
15105   "TARGET_64BIT"
15106   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15107   [(set_attr "type" "multi")
15108    (set_attr "length" "16")])
15110 (define_expand "tls_global_dynamic_64"
15111   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15112                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15113               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15114                          UNSPEC_TLS_GD)])]
15115   ""
15117   if (TARGET_GNU2_TLS)
15118     {
15119        emit_insn (gen_tls_dynamic_gnu2_64
15120                   (operands[0], operands[1]));
15121        DONE;
15122     }
15123   operands[2] = ix86_tls_get_addr ();
15126 (define_insn "*tls_local_dynamic_base_32_gnu"
15127   [(set (match_operand:SI 0 "register_operand" "=a")
15128         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15129                     (match_operand:SI 2 "call_insn_operand" "")]
15130                    UNSPEC_TLS_LD_BASE))
15131    (clobber (match_scratch:SI 3 "=d"))
15132    (clobber (match_scratch:SI 4 "=c"))
15133    (clobber (reg:CC FLAGS_REG))]
15134   "!TARGET_64BIT && TARGET_GNU_TLS"
15135   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15136   [(set_attr "type" "multi")
15137    (set_attr "length" "11")])
15139 (define_insn "*tls_local_dynamic_base_32_sun"
15140   [(set (match_operand:SI 0 "register_operand" "=a")
15141         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15142                     (match_operand:SI 2 "call_insn_operand" "")]
15143                    UNSPEC_TLS_LD_BASE))
15144    (clobber (match_scratch:SI 3 "=d"))
15145    (clobber (match_scratch:SI 4 "=c"))
15146    (clobber (reg:CC FLAGS_REG))]
15147   "!TARGET_64BIT && TARGET_SUN_TLS"
15148   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15149         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15150   [(set_attr "type" "multi")
15151    (set_attr "length" "13")])
15153 (define_expand "tls_local_dynamic_base_32"
15154   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15155                    (unspec:SI [(match_dup 1) (match_dup 2)]
15156                               UNSPEC_TLS_LD_BASE))
15157               (clobber (match_scratch:SI 3 ""))
15158               (clobber (match_scratch:SI 4 ""))
15159               (clobber (reg:CC FLAGS_REG))])]
15160   ""
15162   if (flag_pic)
15163     operands[1] = pic_offset_table_rtx;
15164   else
15165     {
15166       operands[1] = gen_reg_rtx (Pmode);
15167       emit_insn (gen_set_got (operands[1]));
15168     }
15169   if (TARGET_GNU2_TLS)
15170     {
15171        emit_insn (gen_tls_dynamic_gnu2_32
15172                   (operands[0], ix86_tls_module_base (), operands[1]));
15173        DONE;
15174     }
15175   operands[2] = ix86_tls_get_addr ();
15178 (define_insn "*tls_local_dynamic_base_64"
15179   [(set (match_operand:DI 0 "register_operand" "=a")
15180         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15181                  (match_operand:DI 2 "" "")))
15182    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15183   "TARGET_64BIT"
15184   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15185   [(set_attr "type" "multi")
15186    (set_attr "length" "12")])
15188 (define_expand "tls_local_dynamic_base_64"
15189   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15190                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15191               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15192   ""
15194   if (TARGET_GNU2_TLS)
15195     {
15196        emit_insn (gen_tls_dynamic_gnu2_64
15197                   (operands[0], ix86_tls_module_base ()));
15198        DONE;
15199     }
15200   operands[1] = ix86_tls_get_addr ();
15203 ;; Local dynamic of a single variable is a lose.  Show combine how
15204 ;; to convert that back to global dynamic.
15206 (define_insn_and_split "*tls_local_dynamic_32_once"
15207   [(set (match_operand:SI 0 "register_operand" "=a")
15208         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15209                              (match_operand:SI 2 "call_insn_operand" "")]
15210                             UNSPEC_TLS_LD_BASE)
15211                  (const:SI (unspec:SI
15212                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15213                             UNSPEC_DTPOFF))))
15214    (clobber (match_scratch:SI 4 "=d"))
15215    (clobber (match_scratch:SI 5 "=c"))
15216    (clobber (reg:CC FLAGS_REG))]
15217   ""
15218   "#"
15219   ""
15220   [(parallel [(set (match_dup 0)
15221                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15222                               UNSPEC_TLS_GD))
15223               (clobber (match_dup 4))
15224               (clobber (match_dup 5))
15225               (clobber (reg:CC FLAGS_REG))])]
15226   "")
15228 ;; Load and add the thread base pointer from %gs:0.
15230 (define_insn "*load_tp_si"
15231   [(set (match_operand:SI 0 "register_operand" "=r")
15232         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15233   "!TARGET_64BIT"
15234   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15235   [(set_attr "type" "imov")
15236    (set_attr "modrm" "0")
15237    (set_attr "length" "7")
15238    (set_attr "memory" "load")
15239    (set_attr "imm_disp" "false")])
15241 (define_insn "*add_tp_si"
15242   [(set (match_operand:SI 0 "register_operand" "=r")
15243         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15244                  (match_operand:SI 1 "register_operand" "0")))
15245    (clobber (reg:CC FLAGS_REG))]
15246   "!TARGET_64BIT"
15247   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15248   [(set_attr "type" "alu")
15249    (set_attr "modrm" "0")
15250    (set_attr "length" "7")
15251    (set_attr "memory" "load")
15252    (set_attr "imm_disp" "false")])
15254 (define_insn "*load_tp_di"
15255   [(set (match_operand:DI 0 "register_operand" "=r")
15256         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15257   "TARGET_64BIT"
15258   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15259   [(set_attr "type" "imov")
15260    (set_attr "modrm" "0")
15261    (set_attr "length" "7")
15262    (set_attr "memory" "load")
15263    (set_attr "imm_disp" "false")])
15265 (define_insn "*add_tp_di"
15266   [(set (match_operand:DI 0 "register_operand" "=r")
15267         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15268                  (match_operand:DI 1 "register_operand" "0")))
15269    (clobber (reg:CC FLAGS_REG))]
15270   "TARGET_64BIT"
15271   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15272   [(set_attr "type" "alu")
15273    (set_attr "modrm" "0")
15274    (set_attr "length" "7")
15275    (set_attr "memory" "load")
15276    (set_attr "imm_disp" "false")])
15278 ;; GNU2 TLS patterns can be split.
15280 (define_expand "tls_dynamic_gnu2_32"
15281   [(set (match_dup 3)
15282         (plus:SI (match_operand:SI 2 "register_operand" "")
15283                  (const:SI
15284                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15285                              UNSPEC_TLSDESC))))
15286    (parallel
15287     [(set (match_operand:SI 0 "register_operand" "")
15288           (unspec:SI [(match_dup 1) (match_dup 3)
15289                       (match_dup 2) (reg:SI SP_REG)]
15290                       UNSPEC_TLSDESC))
15291      (clobber (reg:CC FLAGS_REG))])]
15292   "!TARGET_64BIT && TARGET_GNU2_TLS"
15294   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15295   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15298 (define_insn "*tls_dynamic_lea_32"
15299   [(set (match_operand:SI 0 "register_operand" "=r")
15300         (plus:SI (match_operand:SI 1 "register_operand" "b")
15301                  (const:SI
15302                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15303                               UNSPEC_TLSDESC))))]
15304   "!TARGET_64BIT && TARGET_GNU2_TLS"
15305   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15306   [(set_attr "type" "lea")
15307    (set_attr "mode" "SI")
15308    (set_attr "length" "6")
15309    (set_attr "length_address" "4")])
15311 (define_insn "*tls_dynamic_call_32"
15312   [(set (match_operand:SI 0 "register_operand" "=a")
15313         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15314                     (match_operand:SI 2 "register_operand" "0")
15315                     ;; we have to make sure %ebx still points to the GOT
15316                     (match_operand:SI 3 "register_operand" "b")
15317                     (reg:SI SP_REG)]
15318                    UNSPEC_TLSDESC))
15319    (clobber (reg:CC FLAGS_REG))]
15320   "!TARGET_64BIT && TARGET_GNU2_TLS"
15321   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15322   [(set_attr "type" "call")
15323    (set_attr "length" "2")
15324    (set_attr "length_address" "0")])
15326 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15327   [(set (match_operand:SI 0 "register_operand" "=&a")
15328         (plus:SI
15329          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15330                      (match_operand:SI 4 "" "")
15331                      (match_operand:SI 2 "register_operand" "b")
15332                      (reg:SI SP_REG)]
15333                     UNSPEC_TLSDESC)
15334          (const:SI (unspec:SI
15335                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15336                     UNSPEC_DTPOFF))))
15337    (clobber (reg:CC FLAGS_REG))]
15338   "!TARGET_64BIT && TARGET_GNU2_TLS"
15339   "#"
15340   ""
15341   [(set (match_dup 0) (match_dup 5))]
15343   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15344   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15347 (define_expand "tls_dynamic_gnu2_64"
15348   [(set (match_dup 2)
15349         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15350                    UNSPEC_TLSDESC))
15351    (parallel
15352     [(set (match_operand:DI 0 "register_operand" "")
15353           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15354                      UNSPEC_TLSDESC))
15355      (clobber (reg:CC FLAGS_REG))])]
15356   "TARGET_64BIT && TARGET_GNU2_TLS"
15358   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15359   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15362 (define_insn "*tls_dynamic_lea_64"
15363   [(set (match_operand:DI 0 "register_operand" "=r")
15364         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15365                    UNSPEC_TLSDESC))]
15366   "TARGET_64BIT && TARGET_GNU2_TLS"
15367   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15368   [(set_attr "type" "lea")
15369    (set_attr "mode" "DI")
15370    (set_attr "length" "7")
15371    (set_attr "length_address" "4")])
15373 (define_insn "*tls_dynamic_call_64"
15374   [(set (match_operand:DI 0 "register_operand" "=a")
15375         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15376                     (match_operand:DI 2 "register_operand" "0")
15377                     (reg:DI SP_REG)]
15378                    UNSPEC_TLSDESC))
15379    (clobber (reg:CC FLAGS_REG))]
15380   "TARGET_64BIT && TARGET_GNU2_TLS"
15381   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15382   [(set_attr "type" "call")
15383    (set_attr "length" "2")
15384    (set_attr "length_address" "0")])
15386 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15387   [(set (match_operand:DI 0 "register_operand" "=&a")
15388         (plus:DI
15389          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15390                      (match_operand:DI 3 "" "")
15391                      (reg:DI SP_REG)]
15392                     UNSPEC_TLSDESC)
15393          (const:DI (unspec:DI
15394                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15395                     UNSPEC_DTPOFF))))
15396    (clobber (reg:CC FLAGS_REG))]
15397   "TARGET_64BIT && TARGET_GNU2_TLS"
15398   "#"
15399   ""
15400   [(set (match_dup 0) (match_dup 4))]
15402   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15403   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15408 ;; These patterns match the binary 387 instructions for addM3, subM3,
15409 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15410 ;; SFmode.  The first is the normal insn, the second the same insn but
15411 ;; with one operand a conversion, and the third the same insn but with
15412 ;; the other operand a conversion.  The conversion may be SFmode or
15413 ;; SImode if the target mode DFmode, but only SImode if the target mode
15414 ;; is SFmode.
15416 ;; Gcc is slightly more smart about handling normal two address instructions
15417 ;; so use special patterns for add and mull.
15419 (define_insn "*fop_sf_comm_mixed"
15420   [(set (match_operand:SF 0 "register_operand" "=f,x")
15421         (match_operator:SF 3 "binary_fp_operator"
15422                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15423                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15424   "TARGET_MIX_SSE_I387
15425    && COMMUTATIVE_ARITH_P (operands[3])
15426    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15427   "* return output_387_binary_op (insn, operands);"
15428   [(set (attr "type")
15429         (if_then_else (eq_attr "alternative" "1")
15430            (if_then_else (match_operand:SF 3 "mult_operator" "")
15431               (const_string "ssemul")
15432               (const_string "sseadd"))
15433            (if_then_else (match_operand:SF 3 "mult_operator" "")
15434               (const_string "fmul")
15435               (const_string "fop"))))
15436    (set_attr "mode" "SF")])
15438 (define_insn "*fop_sf_comm_sse"
15439   [(set (match_operand:SF 0 "register_operand" "=x")
15440         (match_operator:SF 3 "binary_fp_operator"
15441                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15442                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15443   "TARGET_SSE_MATH
15444    && COMMUTATIVE_ARITH_P (operands[3])
15445    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15446   "* return output_387_binary_op (insn, operands);"
15447   [(set (attr "type")
15448         (if_then_else (match_operand:SF 3 "mult_operator" "")
15449            (const_string "ssemul")
15450            (const_string "sseadd")))
15451    (set_attr "mode" "SF")])
15453 (define_insn "*fop_sf_comm_i387"
15454   [(set (match_operand:SF 0 "register_operand" "=f")
15455         (match_operator:SF 3 "binary_fp_operator"
15456                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15457                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15458   "TARGET_80387
15459    && COMMUTATIVE_ARITH_P (operands[3])
15460    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15461   "* return output_387_binary_op (insn, operands);"
15462   [(set (attr "type")
15463         (if_then_else (match_operand:SF 3 "mult_operator" "")
15464            (const_string "fmul")
15465            (const_string "fop")))
15466    (set_attr "mode" "SF")])
15468 (define_insn "*fop_sf_1_mixed"
15469   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15470         (match_operator:SF 3 "binary_fp_operator"
15471                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15472                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15473   "TARGET_MIX_SSE_I387
15474    && !COMMUTATIVE_ARITH_P (operands[3])
15475    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15476   "* return output_387_binary_op (insn, operands);"
15477   [(set (attr "type")
15478         (cond [(and (eq_attr "alternative" "2")
15479                     (match_operand:SF 3 "mult_operator" ""))
15480                  (const_string "ssemul")
15481                (and (eq_attr "alternative" "2")
15482                     (match_operand:SF 3 "div_operator" ""))
15483                  (const_string "ssediv")
15484                (eq_attr "alternative" "2")
15485                  (const_string "sseadd")
15486                (match_operand:SF 3 "mult_operator" "")
15487                  (const_string "fmul")
15488                (match_operand:SF 3 "div_operator" "")
15489                  (const_string "fdiv")
15490               ]
15491               (const_string "fop")))
15492    (set_attr "mode" "SF")])
15494 (define_insn "*fop_sf_1_sse"
15495   [(set (match_operand:SF 0 "register_operand" "=x")
15496         (match_operator:SF 3 "binary_fp_operator"
15497                         [(match_operand:SF 1 "register_operand" "0")
15498                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15499   "TARGET_SSE_MATH
15500    && !COMMUTATIVE_ARITH_P (operands[3])"
15501   "* return output_387_binary_op (insn, operands);"
15502   [(set (attr "type")
15503         (cond [(match_operand:SF 3 "mult_operator" "")
15504                  (const_string "ssemul")
15505                (match_operand:SF 3 "div_operator" "")
15506                  (const_string "ssediv")
15507               ]
15508               (const_string "sseadd")))
15509    (set_attr "mode" "SF")])
15511 ;; This pattern is not fully shadowed by the pattern above.
15512 (define_insn "*fop_sf_1_i387"
15513   [(set (match_operand:SF 0 "register_operand" "=f,f")
15514         (match_operator:SF 3 "binary_fp_operator"
15515                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15516                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15517   "TARGET_80387 && !TARGET_SSE_MATH
15518    && !COMMUTATIVE_ARITH_P (operands[3])
15519    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15520   "* return output_387_binary_op (insn, operands);"
15521   [(set (attr "type")
15522         (cond [(match_operand:SF 3 "mult_operator" "")
15523                  (const_string "fmul")
15524                (match_operand:SF 3 "div_operator" "")
15525                  (const_string "fdiv")
15526               ]
15527               (const_string "fop")))
15528    (set_attr "mode" "SF")])
15530 ;; ??? Add SSE splitters for these!
15531 (define_insn "*fop_sf_2<mode>_i387"
15532   [(set (match_operand:SF 0 "register_operand" "=f,f")
15533         (match_operator:SF 3 "binary_fp_operator"
15534           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15535            (match_operand:SF 2 "register_operand" "0,0")]))]
15536   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15537   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15538   [(set (attr "type")
15539         (cond [(match_operand:SF 3 "mult_operator" "")
15540                  (const_string "fmul")
15541                (match_operand:SF 3 "div_operator" "")
15542                  (const_string "fdiv")
15543               ]
15544               (const_string "fop")))
15545    (set_attr "fp_int_src" "true")
15546    (set_attr "mode" "<MODE>")])
15548 (define_insn "*fop_sf_3<mode>_i387"
15549   [(set (match_operand:SF 0 "register_operand" "=f,f")
15550         (match_operator:SF 3 "binary_fp_operator"
15551           [(match_operand:SF 1 "register_operand" "0,0")
15552            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15553   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15554   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15555   [(set (attr "type")
15556         (cond [(match_operand:SF 3 "mult_operator" "")
15557                  (const_string "fmul")
15558                (match_operand:SF 3 "div_operator" "")
15559                  (const_string "fdiv")
15560               ]
15561               (const_string "fop")))
15562    (set_attr "fp_int_src" "true")
15563    (set_attr "mode" "<MODE>")])
15565 (define_insn "*fop_df_comm_mixed"
15566   [(set (match_operand:DF 0 "register_operand" "=f,x")
15567         (match_operator:DF 3 "binary_fp_operator"
15568           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15569            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15570   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15571    && COMMUTATIVE_ARITH_P (operands[3])
15572    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15573   "* return output_387_binary_op (insn, operands);"
15574   [(set (attr "type")
15575         (if_then_else (eq_attr "alternative" "1")
15576            (if_then_else (match_operand:DF 3 "mult_operator" "")
15577               (const_string "ssemul")
15578               (const_string "sseadd"))
15579            (if_then_else (match_operand:DF 3 "mult_operator" "")
15580               (const_string "fmul")
15581               (const_string "fop"))))
15582    (set_attr "mode" "DF")])
15584 (define_insn "*fop_df_comm_sse"
15585   [(set (match_operand:DF 0 "register_operand" "=x")
15586         (match_operator:DF 3 "binary_fp_operator"
15587           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15588            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15589   "TARGET_SSE2 && TARGET_SSE_MATH
15590    && COMMUTATIVE_ARITH_P (operands[3])
15591    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15592   "* return output_387_binary_op (insn, operands);"
15593   [(set (attr "type")
15594         (if_then_else (match_operand:DF 3 "mult_operator" "")
15595            (const_string "ssemul")
15596            (const_string "sseadd")))
15597    (set_attr "mode" "DF")])
15599 (define_insn "*fop_df_comm_i387"
15600   [(set (match_operand:DF 0 "register_operand" "=f")
15601         (match_operator:DF 3 "binary_fp_operator"
15602                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15603                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15604   "TARGET_80387
15605    && COMMUTATIVE_ARITH_P (operands[3])
15606    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15607   "* return output_387_binary_op (insn, operands);"
15608   [(set (attr "type")
15609         (if_then_else (match_operand:DF 3 "mult_operator" "")
15610            (const_string "fmul")
15611            (const_string "fop")))
15612    (set_attr "mode" "DF")])
15614 (define_insn "*fop_df_1_mixed"
15615   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15616         (match_operator:DF 3 "binary_fp_operator"
15617           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15618            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15619   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15620    && !COMMUTATIVE_ARITH_P (operands[3])
15621    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15622   "* return output_387_binary_op (insn, operands);"
15623   [(set (attr "type")
15624         (cond [(and (eq_attr "alternative" "2")
15625                     (match_operand:DF 3 "mult_operator" ""))
15626                  (const_string "ssemul")
15627                (and (eq_attr "alternative" "2")
15628                     (match_operand:DF 3 "div_operator" ""))
15629                  (const_string "ssediv")
15630                (eq_attr "alternative" "2")
15631                  (const_string "sseadd")
15632                (match_operand:DF 3 "mult_operator" "")
15633                  (const_string "fmul")
15634                (match_operand:DF 3 "div_operator" "")
15635                  (const_string "fdiv")
15636               ]
15637               (const_string "fop")))
15638    (set_attr "mode" "DF")])
15640 (define_insn "*fop_df_1_sse"
15641   [(set (match_operand:DF 0 "register_operand" "=x")
15642         (match_operator:DF 3 "binary_fp_operator"
15643           [(match_operand:DF 1 "register_operand" "0")
15644            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15645   "TARGET_SSE2 && TARGET_SSE_MATH
15646    && !COMMUTATIVE_ARITH_P (operands[3])"
15647   "* return output_387_binary_op (insn, operands);"
15648   [(set_attr "mode" "DF")
15649    (set (attr "type")
15650         (cond [(match_operand:DF 3 "mult_operator" "")
15651                  (const_string "ssemul")
15652                (match_operand:DF 3 "div_operator" "")
15653                  (const_string "ssediv")
15654               ]
15655               (const_string "sseadd")))])
15657 ;; This pattern is not fully shadowed by the pattern above.
15658 (define_insn "*fop_df_1_i387"
15659   [(set (match_operand:DF 0 "register_operand" "=f,f")
15660         (match_operator:DF 3 "binary_fp_operator"
15661                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15662                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15663   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15664    && !COMMUTATIVE_ARITH_P (operands[3])
15665    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15666   "* return output_387_binary_op (insn, operands);"
15667   [(set (attr "type")
15668         (cond [(match_operand:DF 3 "mult_operator" "")
15669                  (const_string "fmul")
15670                (match_operand:DF 3 "div_operator" "")
15671                  (const_string "fdiv")
15672               ]
15673               (const_string "fop")))
15674    (set_attr "mode" "DF")])
15676 ;; ??? Add SSE splitters for these!
15677 (define_insn "*fop_df_2<mode>_i387"
15678   [(set (match_operand:DF 0 "register_operand" "=f,f")
15679         (match_operator:DF 3 "binary_fp_operator"
15680            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15681             (match_operand:DF 2 "register_operand" "0,0")]))]
15682   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15683    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15684   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15685   [(set (attr "type")
15686         (cond [(match_operand:DF 3 "mult_operator" "")
15687                  (const_string "fmul")
15688                (match_operand:DF 3 "div_operator" "")
15689                  (const_string "fdiv")
15690               ]
15691               (const_string "fop")))
15692    (set_attr "fp_int_src" "true")
15693    (set_attr "mode" "<MODE>")])
15695 (define_insn "*fop_df_3<mode>_i387"
15696   [(set (match_operand:DF 0 "register_operand" "=f,f")
15697         (match_operator:DF 3 "binary_fp_operator"
15698            [(match_operand:DF 1 "register_operand" "0,0")
15699             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15700   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15701    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15702   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15703   [(set (attr "type")
15704         (cond [(match_operand:DF 3 "mult_operator" "")
15705                  (const_string "fmul")
15706                (match_operand:DF 3 "div_operator" "")
15707                  (const_string "fdiv")
15708               ]
15709               (const_string "fop")))
15710    (set_attr "fp_int_src" "true")
15711    (set_attr "mode" "<MODE>")])
15713 (define_insn "*fop_df_4_i387"
15714   [(set (match_operand:DF 0 "register_operand" "=f,f")
15715         (match_operator:DF 3 "binary_fp_operator"
15716            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15717             (match_operand:DF 2 "register_operand" "0,f")]))]
15718   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15719    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15720   "* return output_387_binary_op (insn, operands);"
15721   [(set (attr "type")
15722         (cond [(match_operand:DF 3 "mult_operator" "")
15723                  (const_string "fmul")
15724                (match_operand:DF 3 "div_operator" "")
15725                  (const_string "fdiv")
15726               ]
15727               (const_string "fop")))
15728    (set_attr "mode" "SF")])
15730 (define_insn "*fop_df_5_i387"
15731   [(set (match_operand:DF 0 "register_operand" "=f,f")
15732         (match_operator:DF 3 "binary_fp_operator"
15733           [(match_operand:DF 1 "register_operand" "0,f")
15734            (float_extend:DF
15735             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15736   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15737   "* return output_387_binary_op (insn, operands);"
15738   [(set (attr "type")
15739         (cond [(match_operand:DF 3 "mult_operator" "")
15740                  (const_string "fmul")
15741                (match_operand:DF 3 "div_operator" "")
15742                  (const_string "fdiv")
15743               ]
15744               (const_string "fop")))
15745    (set_attr "mode" "SF")])
15747 (define_insn "*fop_df_6_i387"
15748   [(set (match_operand:DF 0 "register_operand" "=f,f")
15749         (match_operator:DF 3 "binary_fp_operator"
15750           [(float_extend:DF
15751             (match_operand:SF 1 "register_operand" "0,f"))
15752            (float_extend:DF
15753             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15754   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15755   "* return output_387_binary_op (insn, operands);"
15756   [(set (attr "type")
15757         (cond [(match_operand:DF 3 "mult_operator" "")
15758                  (const_string "fmul")
15759                (match_operand:DF 3 "div_operator" "")
15760                  (const_string "fdiv")
15761               ]
15762               (const_string "fop")))
15763    (set_attr "mode" "SF")])
15765 (define_insn "*fop_xf_comm_i387"
15766   [(set (match_operand:XF 0 "register_operand" "=f")
15767         (match_operator:XF 3 "binary_fp_operator"
15768                         [(match_operand:XF 1 "register_operand" "%0")
15769                          (match_operand:XF 2 "register_operand" "f")]))]
15770   "TARGET_80387
15771    && COMMUTATIVE_ARITH_P (operands[3])"
15772   "* return output_387_binary_op (insn, operands);"
15773   [(set (attr "type")
15774         (if_then_else (match_operand:XF 3 "mult_operator" "")
15775            (const_string "fmul")
15776            (const_string "fop")))
15777    (set_attr "mode" "XF")])
15779 (define_insn "*fop_xf_1_i387"
15780   [(set (match_operand:XF 0 "register_operand" "=f,f")
15781         (match_operator:XF 3 "binary_fp_operator"
15782                         [(match_operand:XF 1 "register_operand" "0,f")
15783                          (match_operand:XF 2 "register_operand" "f,0")]))]
15784   "TARGET_80387
15785    && !COMMUTATIVE_ARITH_P (operands[3])"
15786   "* return output_387_binary_op (insn, operands);"
15787   [(set (attr "type")
15788         (cond [(match_operand:XF 3 "mult_operator" "")
15789                  (const_string "fmul")
15790                (match_operand:XF 3 "div_operator" "")
15791                  (const_string "fdiv")
15792               ]
15793               (const_string "fop")))
15794    (set_attr "mode" "XF")])
15796 (define_insn "*fop_xf_2<mode>_i387"
15797   [(set (match_operand:XF 0 "register_operand" "=f,f")
15798         (match_operator:XF 3 "binary_fp_operator"
15799            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15800             (match_operand:XF 2 "register_operand" "0,0")]))]
15801   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15802   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15803   [(set (attr "type")
15804         (cond [(match_operand:XF 3 "mult_operator" "")
15805                  (const_string "fmul")
15806                (match_operand:XF 3 "div_operator" "")
15807                  (const_string "fdiv")
15808               ]
15809               (const_string "fop")))
15810    (set_attr "fp_int_src" "true")
15811    (set_attr "mode" "<MODE>")])
15813 (define_insn "*fop_xf_3<mode>_i387"
15814   [(set (match_operand:XF 0 "register_operand" "=f,f")
15815         (match_operator:XF 3 "binary_fp_operator"
15816           [(match_operand:XF 1 "register_operand" "0,0")
15817            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15818   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15819   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15820   [(set (attr "type")
15821         (cond [(match_operand:XF 3 "mult_operator" "")
15822                  (const_string "fmul")
15823                (match_operand:XF 3 "div_operator" "")
15824                  (const_string "fdiv")
15825               ]
15826               (const_string "fop")))
15827    (set_attr "fp_int_src" "true")
15828    (set_attr "mode" "<MODE>")])
15830 (define_insn "*fop_xf_4_i387"
15831   [(set (match_operand:XF 0 "register_operand" "=f,f")
15832         (match_operator:XF 3 "binary_fp_operator"
15833            [(float_extend:XF
15834               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15835             (match_operand:XF 2 "register_operand" "0,f")]))]
15836   "TARGET_80387"
15837   "* return output_387_binary_op (insn, operands);"
15838   [(set (attr "type")
15839         (cond [(match_operand:XF 3 "mult_operator" "")
15840                  (const_string "fmul")
15841                (match_operand:XF 3 "div_operator" "")
15842                  (const_string "fdiv")
15843               ]
15844               (const_string "fop")))
15845    (set_attr "mode" "SF")])
15847 (define_insn "*fop_xf_5_i387"
15848   [(set (match_operand:XF 0 "register_operand" "=f,f")
15849         (match_operator:XF 3 "binary_fp_operator"
15850           [(match_operand:XF 1 "register_operand" "0,f")
15851            (float_extend:XF
15852              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15853   "TARGET_80387"
15854   "* return output_387_binary_op (insn, operands);"
15855   [(set (attr "type")
15856         (cond [(match_operand:XF 3 "mult_operator" "")
15857                  (const_string "fmul")
15858                (match_operand:XF 3 "div_operator" "")
15859                  (const_string "fdiv")
15860               ]
15861               (const_string "fop")))
15862    (set_attr "mode" "SF")])
15864 (define_insn "*fop_xf_6_i387"
15865   [(set (match_operand:XF 0 "register_operand" "=f,f")
15866         (match_operator:XF 3 "binary_fp_operator"
15867           [(float_extend:XF
15868              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15869            (float_extend:XF
15870              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15871   "TARGET_80387"
15872   "* return output_387_binary_op (insn, operands);"
15873   [(set (attr "type")
15874         (cond [(match_operand:XF 3 "mult_operator" "")
15875                  (const_string "fmul")
15876                (match_operand:XF 3 "div_operator" "")
15877                  (const_string "fdiv")
15878               ]
15879               (const_string "fop")))
15880    (set_attr "mode" "SF")])
15882 (define_split
15883   [(set (match_operand 0 "register_operand" "")
15884         (match_operator 3 "binary_fp_operator"
15885            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15886             (match_operand 2 "register_operand" "")]))]
15887   "reload_completed
15888    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15889   [(const_int 0)]
15891   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15892   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15893   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15894                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15895                                           GET_MODE (operands[3]),
15896                                           operands[4],
15897                                           operands[2])));
15898   ix86_free_from_memory (GET_MODE (operands[1]));
15899   DONE;
15902 (define_split
15903   [(set (match_operand 0 "register_operand" "")
15904         (match_operator 3 "binary_fp_operator"
15905            [(match_operand 1 "register_operand" "")
15906             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15907   "reload_completed
15908    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
15909   [(const_int 0)]
15911   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15912   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15913   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15914                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15915                                           GET_MODE (operands[3]),
15916                                           operands[1],
15917                                           operands[4])));
15918   ix86_free_from_memory (GET_MODE (operands[2]));
15919   DONE;
15922 ;; FPU special functions.
15924 ;; This pattern implements a no-op XFmode truncation for
15925 ;; all fancy i386 XFmode math functions.
15927 (define_insn "truncxf<mode>2_i387_noop_unspec"
15928   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15929         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15930         UNSPEC_TRUNC_NOOP))]
15931   "TARGET_USE_FANCY_MATH_387"
15932   "* return output_387_reg_move (insn, operands);"
15933   [(set_attr "type" "fmov")
15934    (set_attr "mode" "<MODE>")])
15936 (define_insn "sqrtxf2"
15937   [(set (match_operand:XF 0 "register_operand" "=f")
15938         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15939   "TARGET_USE_FANCY_MATH_387"
15940   "fsqrt"
15941   [(set_attr "type" "fpspc")
15942    (set_attr "mode" "XF")
15943    (set_attr "athlon_decode" "direct")
15944    (set_attr "amdfam10_decode" "direct")])
15946 (define_insn "sqrt_extend<mode>xf2_i387"
15947   [(set (match_operand:XF 0 "register_operand" "=f")
15948         (sqrt:XF
15949           (float_extend:XF
15950             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15951   "TARGET_USE_FANCY_MATH_387"
15952   "fsqrt"
15953   [(set_attr "type" "fpspc")
15954    (set_attr "mode" "XF")
15955    (set_attr "athlon_decode" "direct")   
15956    (set_attr "amdfam10_decode" "direct")])
15958 (define_insn "*sqrt<mode>2_sse"
15959   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15960         (sqrt:SSEMODEF
15961           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15962   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15963   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15964   [(set_attr "type" "sse")
15965    (set_attr "mode" "<MODE>")
15966    (set_attr "athlon_decode" "*")
15967    (set_attr "amdfam10_decode" "*")])
15969 (define_expand "sqrt<mode>2"
15970   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15971         (sqrt:X87MODEF12
15972           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15973   "TARGET_USE_FANCY_MATH_387
15974    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15976   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15977     {
15978       rtx op0 = gen_reg_rtx (XFmode);
15979       rtx op1 = force_reg (<MODE>mode, operands[1]);
15981       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15982       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15983       DONE;
15984    }
15987 (define_insn "fpremxf4_i387"
15988   [(set (match_operand:XF 0 "register_operand" "=f")
15989         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15990                     (match_operand:XF 3 "register_operand" "1")]
15991                    UNSPEC_FPREM_F))
15992    (set (match_operand:XF 1 "register_operand" "=u")
15993         (unspec:XF [(match_dup 2) (match_dup 3)]
15994                    UNSPEC_FPREM_U))
15995    (set (reg:CCFP FPSR_REG)
15996         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15997                      UNSPEC_C2_FLAG))]
15998   "TARGET_USE_FANCY_MATH_387"
15999   "fprem"
16000   [(set_attr "type" "fpspc")
16001    (set_attr "mode" "XF")])
16003 (define_expand "fmodxf3"
16004   [(use (match_operand:XF 0 "register_operand" ""))
16005    (use (match_operand:XF 1 "register_operand" ""))
16006    (use (match_operand:XF 2 "register_operand" ""))]
16007   "TARGET_USE_FANCY_MATH_387"
16009   rtx label = gen_label_rtx ();
16011   emit_label (label);
16013   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16014                                 operands[1], operands[2]));
16015   ix86_emit_fp_unordered_jump (label);
16016   LABEL_NUSES (label) = 1;
16018   emit_move_insn (operands[0], operands[1]);
16019   DONE;
16022 (define_expand "fmod<mode>3"
16023   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16024    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16025    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16026   "TARGET_USE_FANCY_MATH_387"
16028   rtx label = gen_label_rtx ();
16030   rtx op1 = gen_reg_rtx (XFmode);
16031   rtx op2 = gen_reg_rtx (XFmode);
16033   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16034   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16036   emit_label (label);
16037   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16038   ix86_emit_fp_unordered_jump (label);
16039   LABEL_NUSES (label) = 1;
16041   /* Truncate the result properly for strict SSE math.  */
16042   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16043       && !TARGET_MIX_SSE_I387)
16044     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16045   else
16046     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16048   DONE;
16051 (define_insn "fprem1xf4_i387"
16052   [(set (match_operand:XF 0 "register_operand" "=f")
16053         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16054                     (match_operand:XF 3 "register_operand" "1")]
16055                    UNSPEC_FPREM1_F))
16056    (set (match_operand:XF 1 "register_operand" "=u")
16057         (unspec:XF [(match_dup 2) (match_dup 3)]
16058                    UNSPEC_FPREM1_U))
16059    (set (reg:CCFP FPSR_REG)
16060         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16061                      UNSPEC_C2_FLAG))]
16062   "TARGET_USE_FANCY_MATH_387"
16063   "fprem1"
16064   [(set_attr "type" "fpspc")
16065    (set_attr "mode" "XF")])
16067 (define_expand "remainderxf3"
16068   [(use (match_operand:XF 0 "register_operand" ""))
16069    (use (match_operand:XF 1 "register_operand" ""))
16070    (use (match_operand:XF 2 "register_operand" ""))]
16071   "TARGET_USE_FANCY_MATH_387"
16073   rtx label = gen_label_rtx ();
16075   emit_label (label);
16077   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16078                                  operands[1], operands[2]));
16079   ix86_emit_fp_unordered_jump (label);
16080   LABEL_NUSES (label) = 1;
16082   emit_move_insn (operands[0], operands[1]);
16083   DONE;
16086 (define_expand "remainder<mode>3"
16087   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16088    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16089    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16090   "TARGET_USE_FANCY_MATH_387"
16092   rtx label = gen_label_rtx ();
16094   rtx op1 = gen_reg_rtx (XFmode);
16095   rtx op2 = gen_reg_rtx (XFmode);
16097   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16098   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16100   emit_label (label);
16102   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16103   ix86_emit_fp_unordered_jump (label);
16104   LABEL_NUSES (label) = 1;
16106   /* Truncate the result properly for strict SSE math.  */
16107   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16108       && !TARGET_MIX_SSE_I387)
16109     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16110   else
16111     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16113   DONE;
16116 (define_insn "*sinxf2_i387"
16117   [(set (match_operand:XF 0 "register_operand" "=f")
16118         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16119   "TARGET_USE_FANCY_MATH_387
16120    && flag_unsafe_math_optimizations"
16121   "fsin"
16122   [(set_attr "type" "fpspc")
16123    (set_attr "mode" "XF")])
16125 (define_insn "*sin_extend<mode>xf2_i387"
16126   [(set (match_operand:XF 0 "register_operand" "=f")
16127         (unspec:XF [(float_extend:XF
16128                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16129                    UNSPEC_SIN))]
16130   "TARGET_USE_FANCY_MATH_387
16131    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16132        || TARGET_MIX_SSE_I387)
16133    && flag_unsafe_math_optimizations"
16134   "fsin"
16135   [(set_attr "type" "fpspc")
16136    (set_attr "mode" "XF")])
16138 (define_insn "*cosxf2_i387"
16139   [(set (match_operand:XF 0 "register_operand" "=f")
16140         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16141   "TARGET_USE_FANCY_MATH_387
16142    && flag_unsafe_math_optimizations"
16143   "fcos"
16144   [(set_attr "type" "fpspc")
16145    (set_attr "mode" "XF")])
16147 (define_insn "*cos_extend<mode>xf2_i387"
16148   [(set (match_operand:XF 0 "register_operand" "=f")
16149         (unspec:XF [(float_extend:XF
16150                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16151                    UNSPEC_COS))]
16152   "TARGET_USE_FANCY_MATH_387
16153    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16154        || TARGET_MIX_SSE_I387)
16155    && flag_unsafe_math_optimizations"
16156   "fcos"
16157   [(set_attr "type" "fpspc")
16158    (set_attr "mode" "XF")])
16160 ;; When sincos pattern is defined, sin and cos builtin functions will be
16161 ;; expanded to sincos pattern with one of its outputs left unused.
16162 ;; CSE pass will figure out if two sincos patterns can be combined,
16163 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16164 ;; depending on the unused output.
16166 (define_insn "sincosxf3"
16167   [(set (match_operand:XF 0 "register_operand" "=f")
16168         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16169                    UNSPEC_SINCOS_COS))
16170    (set (match_operand:XF 1 "register_operand" "=u")
16171         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16172   "TARGET_USE_FANCY_MATH_387
16173    && flag_unsafe_math_optimizations"
16174   "fsincos"
16175   [(set_attr "type" "fpspc")
16176    (set_attr "mode" "XF")])
16178 (define_split
16179   [(set (match_operand:XF 0 "register_operand" "")
16180         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16181                    UNSPEC_SINCOS_COS))
16182    (set (match_operand:XF 1 "register_operand" "")
16183         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16184   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16185    && !reload_completed && !reload_in_progress"
16186   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16187   "")
16189 (define_split
16190   [(set (match_operand:XF 0 "register_operand" "")
16191         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16192                    UNSPEC_SINCOS_COS))
16193    (set (match_operand:XF 1 "register_operand" "")
16194         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16195   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16196    && !reload_completed && !reload_in_progress"
16197   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16198   "")
16200 (define_insn "sincos_extend<mode>xf3_i387"
16201   [(set (match_operand:XF 0 "register_operand" "=f")
16202         (unspec:XF [(float_extend:XF
16203                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16204                    UNSPEC_SINCOS_COS))
16205    (set (match_operand:XF 1 "register_operand" "=u")
16206         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16207   "TARGET_USE_FANCY_MATH_387
16208    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16209        || TARGET_MIX_SSE_I387)
16210    && flag_unsafe_math_optimizations"
16211   "fsincos"
16212   [(set_attr "type" "fpspc")
16213    (set_attr "mode" "XF")])
16215 (define_split
16216   [(set (match_operand:XF 0 "register_operand" "")
16217         (unspec:XF [(float_extend:XF
16218                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16219                    UNSPEC_SINCOS_COS))
16220    (set (match_operand:XF 1 "register_operand" "")
16221         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16222   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16223    && !reload_completed && !reload_in_progress"
16224   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16225   "")
16227 (define_split
16228   [(set (match_operand:XF 0 "register_operand" "")
16229         (unspec:XF [(float_extend:XF
16230                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16231                    UNSPEC_SINCOS_COS))
16232    (set (match_operand:XF 1 "register_operand" "")
16233         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16234   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16235    && !reload_completed && !reload_in_progress"
16236   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16237   "")
16239 (define_expand "sincos<mode>3"
16240   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16241    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16242    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16243   "TARGET_USE_FANCY_MATH_387
16244    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16245        || TARGET_MIX_SSE_I387)
16246    && flag_unsafe_math_optimizations"
16248   rtx op0 = gen_reg_rtx (XFmode);
16249   rtx op1 = gen_reg_rtx (XFmode);
16251   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16252   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16253   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16254   DONE;
16257 (define_insn "fptanxf4_i387"
16258   [(set (match_operand:XF 0 "register_operand" "=f")
16259         (match_operand:XF 3 "const_double_operand" "F"))
16260    (set (match_operand:XF 1 "register_operand" "=u")
16261         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16262                    UNSPEC_TAN))]
16263   "TARGET_USE_FANCY_MATH_387
16264    && flag_unsafe_math_optimizations
16265    && standard_80387_constant_p (operands[3]) == 2"
16266   "fptan"
16267   [(set_attr "type" "fpspc")
16268    (set_attr "mode" "XF")])
16270 (define_insn "fptan_extend<mode>xf4_i387"
16271   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16272         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16273    (set (match_operand:XF 1 "register_operand" "=u")
16274         (unspec:XF [(float_extend:XF
16275                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16276                    UNSPEC_TAN))]
16277   "TARGET_USE_FANCY_MATH_387
16278    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16279        || TARGET_MIX_SSE_I387)
16280    && flag_unsafe_math_optimizations
16281    && standard_80387_constant_p (operands[3]) == 2"
16282   "fptan"
16283   [(set_attr "type" "fpspc")
16284    (set_attr "mode" "XF")])
16286 (define_expand "tanxf2"
16287   [(use (match_operand:XF 0 "register_operand" ""))
16288    (use (match_operand:XF 1 "register_operand" ""))]
16289   "TARGET_USE_FANCY_MATH_387
16290    && flag_unsafe_math_optimizations"
16292   rtx one = gen_reg_rtx (XFmode);
16293   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16295   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16296   DONE;
16299 (define_expand "tan<mode>2"
16300   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16301    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16302   "TARGET_USE_FANCY_MATH_387
16303    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16304        || TARGET_MIX_SSE_I387)
16305    && flag_unsafe_math_optimizations"
16307   rtx op0 = gen_reg_rtx (XFmode);
16309   rtx one = gen_reg_rtx (<MODE>mode);
16310   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16312   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16313                                              operands[1], op2));
16314   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16315   DONE;
16318 (define_insn "*fpatanxf3_i387"
16319   [(set (match_operand:XF 0 "register_operand" "=f")
16320         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16321                     (match_operand:XF 2 "register_operand" "u")]
16322                    UNSPEC_FPATAN))
16323    (clobber (match_scratch:XF 3 "=2"))]
16324   "TARGET_USE_FANCY_MATH_387
16325    && flag_unsafe_math_optimizations"
16326   "fpatan"
16327   [(set_attr "type" "fpspc")
16328    (set_attr "mode" "XF")])
16330 (define_insn "fpatan_extend<mode>xf3_i387"
16331   [(set (match_operand:XF 0 "register_operand" "=f")
16332         (unspec:XF [(float_extend:XF
16333                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16334                     (float_extend:XF
16335                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16336                    UNSPEC_FPATAN))
16337    (clobber (match_scratch:XF 3 "=2"))]
16338   "TARGET_USE_FANCY_MATH_387
16339    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16340        || TARGET_MIX_SSE_I387)
16341    && flag_unsafe_math_optimizations"
16342   "fpatan"
16343   [(set_attr "type" "fpspc")
16344    (set_attr "mode" "XF")])
16346 (define_expand "atan2xf3"
16347   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16348                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16349                                (match_operand:XF 1 "register_operand" "")]
16350                               UNSPEC_FPATAN))
16351               (clobber (match_scratch:XF 3 ""))])]
16352   "TARGET_USE_FANCY_MATH_387
16353    && flag_unsafe_math_optimizations"
16354   "")
16356 (define_expand "atan2<mode>3"
16357   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16358    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16359    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16360   "TARGET_USE_FANCY_MATH_387
16361    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16362        || TARGET_MIX_SSE_I387)
16363    && flag_unsafe_math_optimizations"
16365   rtx op0 = gen_reg_rtx (XFmode);
16367   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16368   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16369   DONE;
16372 (define_expand "atanxf2"
16373   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16374                    (unspec:XF [(match_dup 2)
16375                                (match_operand:XF 1 "register_operand" "")]
16376                               UNSPEC_FPATAN))
16377               (clobber (match_scratch:XF 3 ""))])]
16378   "TARGET_USE_FANCY_MATH_387
16379    && flag_unsafe_math_optimizations"
16381   operands[2] = gen_reg_rtx (XFmode);
16382   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16385 (define_expand "atan<mode>2"
16386   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16387    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16388   "TARGET_USE_FANCY_MATH_387
16389    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16390        || TARGET_MIX_SSE_I387)
16391    && flag_unsafe_math_optimizations"
16393   rtx op0 = gen_reg_rtx (XFmode);
16395   rtx op2 = gen_reg_rtx (<MODE>mode);
16396   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16398   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16399   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16400   DONE;
16403 (define_expand "asinxf2"
16404   [(set (match_dup 2)
16405         (mult:XF (match_operand:XF 1 "register_operand" "")
16406                  (match_dup 1)))
16407    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16408    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16409    (parallel [(set (match_operand:XF 0 "register_operand" "")
16410                    (unspec:XF [(match_dup 5) (match_dup 1)]
16411                               UNSPEC_FPATAN))
16412               (clobber (match_scratch:XF 6 ""))])]
16413   "TARGET_USE_FANCY_MATH_387
16414    && flag_unsafe_math_optimizations && !optimize_size"
16416   int i;
16418   for (i = 2; i < 6; i++)
16419     operands[i] = gen_reg_rtx (XFmode);
16421   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16424 (define_expand "asin<mode>2"
16425   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16426    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16427  "TARGET_USE_FANCY_MATH_387
16428    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16429        || TARGET_MIX_SSE_I387)
16430    && flag_unsafe_math_optimizations && !optimize_size"
16432   rtx op0 = gen_reg_rtx (XFmode);
16433   rtx op1 = gen_reg_rtx (XFmode);
16435   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16436   emit_insn (gen_asinxf2 (op0, op1));
16437   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16438   DONE;
16441 (define_expand "acosxf2"
16442   [(set (match_dup 2)
16443         (mult:XF (match_operand:XF 1 "register_operand" "")
16444                  (match_dup 1)))
16445    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16446    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16447    (parallel [(set (match_operand:XF 0 "register_operand" "")
16448                    (unspec:XF [(match_dup 1) (match_dup 5)]
16449                               UNSPEC_FPATAN))
16450               (clobber (match_scratch:XF 6 ""))])]
16451   "TARGET_USE_FANCY_MATH_387
16452    && flag_unsafe_math_optimizations && !optimize_size"
16454   int i;
16456   for (i = 2; i < 6; i++)
16457     operands[i] = gen_reg_rtx (XFmode);
16459   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16462 (define_expand "acos<mode>2"
16463   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16464    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16465  "TARGET_USE_FANCY_MATH_387
16466    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16467        || TARGET_MIX_SSE_I387)
16468    && flag_unsafe_math_optimizations && !optimize_size"
16470   rtx op0 = gen_reg_rtx (XFmode);
16471   rtx op1 = gen_reg_rtx (XFmode);
16473   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16474   emit_insn (gen_acosxf2 (op0, op1));
16475   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16476   DONE;
16479 (define_insn "fyl2xxf3_i387"
16480   [(set (match_operand:XF 0 "register_operand" "=f")
16481         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16482                     (match_operand:XF 2 "register_operand" "u")]
16483                    UNSPEC_FYL2X))
16484    (clobber (match_scratch:XF 3 "=2"))]
16485   "TARGET_USE_FANCY_MATH_387
16486    && flag_unsafe_math_optimizations"
16487   "fyl2x"
16488   [(set_attr "type" "fpspc")
16489    (set_attr "mode" "XF")])
16491 (define_insn "fyl2x_extend<mode>xf3_i387"
16492   [(set (match_operand:XF 0 "register_operand" "=f")
16493         (unspec:XF [(float_extend:XF
16494                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16495                     (match_operand:XF 2 "register_operand" "u")]
16496                    UNSPEC_FYL2X))
16497    (clobber (match_scratch:XF 3 "=2"))]
16498   "TARGET_USE_FANCY_MATH_387
16499    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16500        || TARGET_MIX_SSE_I387)
16501    && flag_unsafe_math_optimizations"
16502   "fyl2x"
16503   [(set_attr "type" "fpspc")
16504    (set_attr "mode" "XF")])
16506 (define_expand "logxf2"
16507   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16508                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16509                                (match_dup 2)] UNSPEC_FYL2X))
16510               (clobber (match_scratch:XF 3 ""))])]
16511   "TARGET_USE_FANCY_MATH_387
16512    && flag_unsafe_math_optimizations"
16514   operands[2] = gen_reg_rtx (XFmode);
16515   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16518 (define_expand "log<mode>2"
16519   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16520    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16521   "TARGET_USE_FANCY_MATH_387
16522    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16523        || TARGET_MIX_SSE_I387)
16524    && flag_unsafe_math_optimizations"
16526   rtx op0 = gen_reg_rtx (XFmode);
16528   rtx op2 = gen_reg_rtx (XFmode);
16529   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16531   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16532   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16533   DONE;
16536 (define_expand "log10xf2"
16537   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16538                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16539                                (match_dup 2)] UNSPEC_FYL2X))
16540               (clobber (match_scratch:XF 3 ""))])]
16541   "TARGET_USE_FANCY_MATH_387
16542    && flag_unsafe_math_optimizations"
16544   operands[2] = gen_reg_rtx (XFmode);
16545   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16548 (define_expand "log10<mode>2"
16549   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16550    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16551   "TARGET_USE_FANCY_MATH_387
16552    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16553        || TARGET_MIX_SSE_I387)
16554    && flag_unsafe_math_optimizations"
16556   rtx op0 = gen_reg_rtx (XFmode);
16558   rtx op2 = gen_reg_rtx (XFmode);
16559   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16561   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16562   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16563   DONE;
16566 (define_expand "log2xf2"
16567   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16568                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16569                                (match_dup 2)] UNSPEC_FYL2X))
16570               (clobber (match_scratch:XF 3 ""))])]
16571   "TARGET_USE_FANCY_MATH_387
16572    && flag_unsafe_math_optimizations"
16574   operands[2] = gen_reg_rtx (XFmode);
16575   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16578 (define_expand "log2<mode>2"
16579   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16580    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16581   "TARGET_USE_FANCY_MATH_387
16582    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16583        || TARGET_MIX_SSE_I387)
16584    && flag_unsafe_math_optimizations"
16586   rtx op0 = gen_reg_rtx (XFmode);
16588   rtx op2 = gen_reg_rtx (XFmode);
16589   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16591   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16592   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16593   DONE;
16596 (define_insn "fyl2xp1xf3_i387"
16597   [(set (match_operand:XF 0 "register_operand" "=f")
16598         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16599                     (match_operand:XF 2 "register_operand" "u")]
16600                    UNSPEC_FYL2XP1))
16601    (clobber (match_scratch:XF 3 "=2"))]
16602   "TARGET_USE_FANCY_MATH_387
16603    && flag_unsafe_math_optimizations"
16604   "fyl2xp1"
16605   [(set_attr "type" "fpspc")
16606    (set_attr "mode" "XF")])
16608 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16609   [(set (match_operand:XF 0 "register_operand" "=f")
16610         (unspec:XF [(float_extend:XF
16611                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16612                     (match_operand:XF 2 "register_operand" "u")]
16613                    UNSPEC_FYL2XP1))
16614    (clobber (match_scratch:XF 3 "=2"))]
16615   "TARGET_USE_FANCY_MATH_387
16616    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16617        || TARGET_MIX_SSE_I387)
16618    && flag_unsafe_math_optimizations"
16619   "fyl2xp1"
16620   [(set_attr "type" "fpspc")
16621    (set_attr "mode" "XF")])
16623 (define_expand "log1pxf2"
16624   [(use (match_operand:XF 0 "register_operand" ""))
16625    (use (match_operand:XF 1 "register_operand" ""))]
16626   "TARGET_USE_FANCY_MATH_387
16627    && flag_unsafe_math_optimizations && !optimize_size"
16629   ix86_emit_i387_log1p (operands[0], operands[1]);
16630   DONE;
16633 (define_expand "log1p<mode>2"
16634   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16635    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16636   "TARGET_USE_FANCY_MATH_387
16637    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16638        || TARGET_MIX_SSE_I387)
16639    && flag_unsafe_math_optimizations && !optimize_size"
16641   rtx op0 = gen_reg_rtx (XFmode);
16643   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16645   ix86_emit_i387_log1p (op0, operands[1]);
16646   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16647   DONE;
16650 (define_insn "fxtractxf3_i387"
16651   [(set (match_operand:XF 0 "register_operand" "=f")
16652         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16653                    UNSPEC_XTRACT_FRACT))
16654    (set (match_operand:XF 1 "register_operand" "=u")
16655         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16656   "TARGET_USE_FANCY_MATH_387
16657    && flag_unsafe_math_optimizations"
16658   "fxtract"
16659   [(set_attr "type" "fpspc")
16660    (set_attr "mode" "XF")])
16662 (define_insn "fxtract_extend<mode>xf3_i387"
16663   [(set (match_operand:XF 0 "register_operand" "=f")
16664         (unspec:XF [(float_extend:XF
16665                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16666                    UNSPEC_XTRACT_FRACT))
16667    (set (match_operand:XF 1 "register_operand" "=u")
16668         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16669   "TARGET_USE_FANCY_MATH_387
16670    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16671        || TARGET_MIX_SSE_I387)
16672    && flag_unsafe_math_optimizations"
16673   "fxtract"
16674   [(set_attr "type" "fpspc")
16675    (set_attr "mode" "XF")])
16677 (define_expand "logbxf2"
16678   [(parallel [(set (match_dup 2)
16679                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16680                               UNSPEC_XTRACT_FRACT))
16681               (set (match_operand:XF 0 "register_operand" "")
16682                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16683   "TARGET_USE_FANCY_MATH_387
16684    && flag_unsafe_math_optimizations"
16686   operands[2] = gen_reg_rtx (XFmode);
16689 (define_expand "logb<mode>2"
16690   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16691    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16692   "TARGET_USE_FANCY_MATH_387
16693    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16694        || TARGET_MIX_SSE_I387)
16695    && flag_unsafe_math_optimizations"
16697   rtx op0 = gen_reg_rtx (XFmode);
16698   rtx op1 = gen_reg_rtx (XFmode);
16700   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16701   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16702   DONE;
16705 (define_expand "ilogbxf2"
16706   [(use (match_operand:SI 0 "register_operand" ""))
16707    (use (match_operand:XF 1 "register_operand" ""))]
16708   "TARGET_USE_FANCY_MATH_387
16709    && flag_unsafe_math_optimizations && !optimize_size"
16711   rtx op0 = gen_reg_rtx (XFmode);
16712   rtx op1 = gen_reg_rtx (XFmode);
16714   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16715   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16716   DONE;
16719 (define_expand "ilogb<mode>2"
16720   [(use (match_operand:SI 0 "register_operand" ""))
16721    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16722   "TARGET_USE_FANCY_MATH_387
16723    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16724        || TARGET_MIX_SSE_I387)
16725    && flag_unsafe_math_optimizations && !optimize_size"
16727   rtx op0 = gen_reg_rtx (XFmode);
16728   rtx op1 = gen_reg_rtx (XFmode);
16730   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16731   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16732   DONE;
16735 (define_insn "*f2xm1xf2_i387"
16736   [(set (match_operand:XF 0 "register_operand" "=f")
16737         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16738                    UNSPEC_F2XM1))]
16739   "TARGET_USE_FANCY_MATH_387
16740    && flag_unsafe_math_optimizations"
16741   "f2xm1"
16742   [(set_attr "type" "fpspc")
16743    (set_attr "mode" "XF")])
16745 (define_insn "*fscalexf4_i387"
16746   [(set (match_operand:XF 0 "register_operand" "=f")
16747         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16748                     (match_operand:XF 3 "register_operand" "1")]
16749                    UNSPEC_FSCALE_FRACT))
16750    (set (match_operand:XF 1 "register_operand" "=u")
16751         (unspec:XF [(match_dup 2) (match_dup 3)]
16752                    UNSPEC_FSCALE_EXP))]
16753   "TARGET_USE_FANCY_MATH_387
16754    && flag_unsafe_math_optimizations"
16755   "fscale"
16756   [(set_attr "type" "fpspc")
16757    (set_attr "mode" "XF")])
16759 (define_expand "expNcorexf3"
16760   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16761                                (match_operand:XF 2 "register_operand" "")))
16762    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16763    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16764    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16765    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16766    (parallel [(set (match_operand:XF 0 "register_operand" "")
16767                    (unspec:XF [(match_dup 8) (match_dup 4)]
16768                               UNSPEC_FSCALE_FRACT))
16769               (set (match_dup 9)
16770                    (unspec:XF [(match_dup 8) (match_dup 4)]
16771                               UNSPEC_FSCALE_EXP))])]
16772   "TARGET_USE_FANCY_MATH_387
16773    && flag_unsafe_math_optimizations && !optimize_size"
16775   int i;
16777   for (i = 3; i < 10; i++)
16778     operands[i] = gen_reg_rtx (XFmode);
16780   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16783 (define_expand "expxf2"
16784   [(use (match_operand:XF 0 "register_operand" ""))
16785    (use (match_operand:XF 1 "register_operand" ""))]
16786   "TARGET_USE_FANCY_MATH_387
16787    && flag_unsafe_math_optimizations && !optimize_size"
16789   rtx op2 = gen_reg_rtx (XFmode);
16790   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16792   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16793   DONE;
16796 (define_expand "exp<mode>2"
16797   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16798    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16799  "TARGET_USE_FANCY_MATH_387
16800    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16801        || TARGET_MIX_SSE_I387)
16802    && flag_unsafe_math_optimizations && !optimize_size"
16804   rtx op0 = gen_reg_rtx (XFmode);
16805   rtx op1 = gen_reg_rtx (XFmode);
16807   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16808   emit_insn (gen_expxf2 (op0, op1));
16809   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16810   DONE;
16813 (define_expand "exp10xf2"
16814   [(use (match_operand:XF 0 "register_operand" ""))
16815    (use (match_operand:XF 1 "register_operand" ""))]
16816   "TARGET_USE_FANCY_MATH_387
16817    && flag_unsafe_math_optimizations && !optimize_size"
16819   rtx op2 = gen_reg_rtx (XFmode);
16820   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16822   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16823   DONE;
16826 (define_expand "exp10<mode>2"
16827   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16828    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16829  "TARGET_USE_FANCY_MATH_387
16830    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16831        || TARGET_MIX_SSE_I387)
16832    && flag_unsafe_math_optimizations && !optimize_size"
16834   rtx op0 = gen_reg_rtx (XFmode);
16835   rtx op1 = gen_reg_rtx (XFmode);
16837   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16838   emit_insn (gen_exp10xf2 (op0, op1));
16839   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16840   DONE;
16843 (define_expand "exp2xf2"
16844   [(use (match_operand:XF 0 "register_operand" ""))
16845    (use (match_operand:XF 1 "register_operand" ""))]
16846   "TARGET_USE_FANCY_MATH_387
16847    && flag_unsafe_math_optimizations && !optimize_size"
16849   rtx op2 = gen_reg_rtx (XFmode);
16850   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16852   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16853   DONE;
16856 (define_expand "exp2<mode>2"
16857   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16858    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16859  "TARGET_USE_FANCY_MATH_387
16860    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16861        || TARGET_MIX_SSE_I387)
16862    && flag_unsafe_math_optimizations && !optimize_size"
16864   rtx op0 = gen_reg_rtx (XFmode);
16865   rtx op1 = gen_reg_rtx (XFmode);
16867   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16868   emit_insn (gen_exp2xf2 (op0, op1));
16869   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16870   DONE;
16873 (define_expand "expm1xf2"
16874   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16875                                (match_dup 2)))
16876    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16877    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16878    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16879    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16880    (parallel [(set (match_dup 7)
16881                    (unspec:XF [(match_dup 6) (match_dup 4)]
16882                               UNSPEC_FSCALE_FRACT))
16883               (set (match_dup 8)
16884                    (unspec:XF [(match_dup 6) (match_dup 4)]
16885                               UNSPEC_FSCALE_EXP))])
16886    (parallel [(set (match_dup 10)
16887                    (unspec:XF [(match_dup 9) (match_dup 8)]
16888                               UNSPEC_FSCALE_FRACT))
16889               (set (match_dup 11)
16890                    (unspec:XF [(match_dup 9) (match_dup 8)]
16891                               UNSPEC_FSCALE_EXP))])
16892    (set (match_dup 12) (minus:XF (match_dup 10)
16893                                  (float_extend:XF (match_dup 13))))
16894    (set (match_operand:XF 0 "register_operand" "")
16895         (plus:XF (match_dup 12) (match_dup 7)))]
16896   "TARGET_USE_FANCY_MATH_387
16897    && flag_unsafe_math_optimizations && !optimize_size"
16899   int i;
16901   for (i = 2; i < 13; i++)
16902     operands[i] = gen_reg_rtx (XFmode);
16904   operands[13]
16905     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16907   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16910 (define_expand "expm1<mode>2"
16911   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16912    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16913  "TARGET_USE_FANCY_MATH_387
16914    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16915        || TARGET_MIX_SSE_I387)
16916    && flag_unsafe_math_optimizations && !optimize_size"
16918   rtx op0 = gen_reg_rtx (XFmode);
16919   rtx op1 = gen_reg_rtx (XFmode);
16921   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16922   emit_insn (gen_expm1xf2 (op0, op1));
16923   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16924   DONE;
16927 (define_expand "ldexpxf3"
16928   [(set (match_dup 3)
16929         (float:XF (match_operand:SI 2 "register_operand" "")))
16930    (parallel [(set (match_operand:XF 0 " register_operand" "")
16931                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16932                                (match_dup 3)]
16933                               UNSPEC_FSCALE_FRACT))
16934               (set (match_dup 4)
16935                    (unspec:XF [(match_dup 1) (match_dup 3)]
16936                               UNSPEC_FSCALE_EXP))])]
16937   "TARGET_USE_FANCY_MATH_387
16938    && flag_unsafe_math_optimizations && !optimize_size"
16940   operands[3] = gen_reg_rtx (XFmode);
16941   operands[4] = gen_reg_rtx (XFmode);
16944 (define_expand "ldexp<mode>3"
16945   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16946    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16947    (use (match_operand:SI 2 "register_operand" ""))]
16948  "TARGET_USE_FANCY_MATH_387
16949    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16950        || TARGET_MIX_SSE_I387)
16951    && flag_unsafe_math_optimizations && !optimize_size"
16953   rtx op0 = gen_reg_rtx (XFmode);
16954   rtx op1 = gen_reg_rtx (XFmode);
16956   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16957   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16958   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16959   DONE;
16962 (define_expand "scalbxf3"
16963   [(parallel [(set (match_operand:XF 0 " register_operand" "")
16964                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16965                                (match_operand:XF 2 "register_operand" "")]
16966                               UNSPEC_FSCALE_FRACT))
16967               (set (match_dup 3)
16968                    (unspec:XF [(match_dup 1) (match_dup 2)]
16969                               UNSPEC_FSCALE_EXP))])]
16970   "TARGET_USE_FANCY_MATH_387
16971    && flag_unsafe_math_optimizations && !optimize_size"
16973   operands[3] = gen_reg_rtx (XFmode);
16976 (define_expand "scalb<mode>3"
16977   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16978    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16979    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16980  "TARGET_USE_FANCY_MATH_387
16981    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16982        || TARGET_MIX_SSE_I387)
16983    && flag_unsafe_math_optimizations && !optimize_size"
16985   rtx op0 = gen_reg_rtx (XFmode);
16986   rtx op1 = gen_reg_rtx (XFmode);
16987   rtx op2 = gen_reg_rtx (XFmode);
16989   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16990   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16991   emit_insn (gen_scalbxf3 (op0, op1, op2));
16992   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16993   DONE;
16997 (define_insn "rintxf2"
16998   [(set (match_operand:XF 0 "register_operand" "=f")
16999         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17000                    UNSPEC_FRNDINT))]
17001   "TARGET_USE_FANCY_MATH_387
17002    && flag_unsafe_math_optimizations"
17003   "frndint"
17004   [(set_attr "type" "fpspc")
17005    (set_attr "mode" "XF")])
17007 (define_expand "rint<mode>2"
17008   [(use (match_operand:SSEMODEF 0 "register_operand" ""))
17009    (use (match_operand:SSEMODEF 1 "register_operand" ""))]
17010   "(TARGET_USE_FANCY_MATH_387
17011     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17012         || TARGET_MIX_SSE_I387)
17013     && flag_unsafe_math_optimizations)
17014    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17015        && !flag_trapping_math
17016        && !optimize_size)"
17018   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17019       && !flag_trapping_math
17020       && !optimize_size)
17021     ix86_expand_rint (operand0, operand1);
17022   else
17023     {
17024       rtx op0 = gen_reg_rtx (XFmode);
17025       rtx op1 = gen_reg_rtx (XFmode);
17027       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17028       emit_insn (gen_rintxf2 (op0, op1));
17030       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17031     }
17032   DONE;
17035 (define_expand "round<mode>2"
17036   [(match_operand:SSEMODEF 0 "register_operand" "")
17037    (match_operand:SSEMODEF 1 "nonimmediate_operand" "")]
17038   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17039    && !flag_trapping_math && !flag_rounding_math
17040    && !optimize_size"
17042   if ((<MODE>mode != DFmode) || TARGET_64BIT)
17043     ix86_expand_round (operand0, operand1);
17044   else
17045     ix86_expand_rounddf_32 (operand0, operand1);
17046   DONE;
17049 (define_insn_and_split "*fistdi2_1"
17050   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17051         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17052                    UNSPEC_FIST))]
17053   "TARGET_USE_FANCY_MATH_387
17054    && !(reload_completed || reload_in_progress)"
17055   "#"
17056   "&& 1"
17057   [(const_int 0)]
17059   if (memory_operand (operands[0], VOIDmode))
17060     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17061   else
17062     {
17063       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17064       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17065                                          operands[2]));
17066     }
17067   DONE;
17069   [(set_attr "type" "fpspc")
17070    (set_attr "mode" "DI")])
17072 (define_insn "fistdi2"
17073   [(set (match_operand:DI 0 "memory_operand" "=m")
17074         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17075                    UNSPEC_FIST))
17076    (clobber (match_scratch:XF 2 "=&1f"))]
17077   "TARGET_USE_FANCY_MATH_387"
17078   "* return output_fix_trunc (insn, operands, 0);"
17079   [(set_attr "type" "fpspc")
17080    (set_attr "mode" "DI")])
17082 (define_insn "fistdi2_with_temp"
17083   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17084         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17085                    UNSPEC_FIST))
17086    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17087    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17088   "TARGET_USE_FANCY_MATH_387"
17089   "#"
17090   [(set_attr "type" "fpspc")
17091    (set_attr "mode" "DI")])
17093 (define_split
17094   [(set (match_operand:DI 0 "register_operand" "")
17095         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17096                    UNSPEC_FIST))
17097    (clobber (match_operand:DI 2 "memory_operand" ""))
17098    (clobber (match_scratch 3 ""))]
17099   "reload_completed"
17100   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17101               (clobber (match_dup 3))])
17102    (set (match_dup 0) (match_dup 2))]
17103   "")
17105 (define_split
17106   [(set (match_operand:DI 0 "memory_operand" "")
17107         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17108                    UNSPEC_FIST))
17109    (clobber (match_operand:DI 2 "memory_operand" ""))
17110    (clobber (match_scratch 3 ""))]
17111   "reload_completed"
17112   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17113               (clobber (match_dup 3))])]
17114   "")
17116 (define_insn_and_split "*fist<mode>2_1"
17117   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17118         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17119                            UNSPEC_FIST))]
17120   "TARGET_USE_FANCY_MATH_387
17121    && !(reload_completed || reload_in_progress)"
17122   "#"
17123   "&& 1"
17124   [(const_int 0)]
17126   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17127   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17128                                         operands[2]));
17129   DONE;
17131   [(set_attr "type" "fpspc")
17132    (set_attr "mode" "<MODE>")])
17134 (define_insn "fist<mode>2"
17135   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17136         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17137                            UNSPEC_FIST))]
17138   "TARGET_USE_FANCY_MATH_387"
17139   "* return output_fix_trunc (insn, operands, 0);"
17140   [(set_attr "type" "fpspc")
17141    (set_attr "mode" "<MODE>")])
17143 (define_insn "fist<mode>2_with_temp"
17144   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17145         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17146                            UNSPEC_FIST))
17147    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17148   "TARGET_USE_FANCY_MATH_387"
17149   "#"
17150   [(set_attr "type" "fpspc")
17151    (set_attr "mode" "<MODE>")])
17153 (define_split
17154   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17155         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17156                            UNSPEC_FIST))
17157    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17158   "reload_completed"
17159   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17160    (set (match_dup 0) (match_dup 2))]
17161   "")
17163 (define_split
17164   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17165         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17166                            UNSPEC_FIST))
17167    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17168   "reload_completed"
17169   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17170   "")
17172 (define_expand "lrintxf<mode>2"
17173   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17174      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17175                       UNSPEC_FIST))]
17176   "TARGET_USE_FANCY_MATH_387"
17177   "")
17179 (define_expand "lrint<SSEMODEF:mode><SSEMODEI24:mode>2"
17180   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17181      (unspec:SSEMODEI24 [(match_operand:SSEMODEF 1 "register_operand" "")]
17182                         UNSPEC_FIX_NOTRUNC))]
17183   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17184    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17185   "")
17187 (define_expand "lround<SSEMODEF:mode><SSEMODEI24:mode>2"
17188   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17189    (match_operand:SSEMODEF 1 "register_operand" "")]
17190   "SSE_FLOAT_MODE_P (<SSEMODEF:MODE>mode) && TARGET_SSE_MATH
17191    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17192    && !flag_trapping_math && !flag_rounding_math
17193    && !optimize_size"
17195   ix86_expand_lround (operand0, operand1);
17196   DONE;
17199 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17200 (define_insn_and_split "frndintxf2_floor"
17201   [(set (match_operand:XF 0 "register_operand" "=f")
17202         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17203          UNSPEC_FRNDINT_FLOOR))
17204    (clobber (reg:CC FLAGS_REG))]
17205   "TARGET_USE_FANCY_MATH_387
17206    && flag_unsafe_math_optimizations
17207    && !(reload_completed || reload_in_progress)"
17208   "#"
17209   "&& 1"
17210   [(const_int 0)]
17212   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17214   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17215   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17217   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17218                                         operands[2], operands[3]));
17219   DONE;
17221   [(set_attr "type" "frndint")
17222    (set_attr "i387_cw" "floor")
17223    (set_attr "mode" "XF")])
17225 (define_insn "frndintxf2_floor_i387"
17226   [(set (match_operand:XF 0 "register_operand" "=f")
17227         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17228          UNSPEC_FRNDINT_FLOOR))
17229    (use (match_operand:HI 2 "memory_operand" "m"))
17230    (use (match_operand:HI 3 "memory_operand" "m"))]
17231   "TARGET_USE_FANCY_MATH_387
17232    && flag_unsafe_math_optimizations"
17233   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17234   [(set_attr "type" "frndint")
17235    (set_attr "i387_cw" "floor")
17236    (set_attr "mode" "XF")])
17238 (define_expand "floorxf2"
17239   [(use (match_operand:XF 0 "register_operand" ""))
17240    (use (match_operand:XF 1 "register_operand" ""))]
17241   "TARGET_USE_FANCY_MATH_387
17242    && flag_unsafe_math_optimizations && !optimize_size"
17244   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17245   DONE;
17248 (define_expand "floordf2"
17249   [(use (match_operand:DF 0 "register_operand" ""))
17250    (use (match_operand:DF 1 "register_operand" ""))]
17251   "((TARGET_USE_FANCY_MATH_387
17252      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17253      && flag_unsafe_math_optimizations)
17254     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17255         && !flag_trapping_math))
17256    && !optimize_size"
17258   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17259       && !flag_trapping_math)
17260     {
17261       if (TARGET_64BIT)
17262         ix86_expand_floorceil (operand0, operand1, true);
17263       else
17264         ix86_expand_floorceildf_32 (operand0, operand1, true);
17265     }
17266   else
17267     {
17268       rtx op0 = gen_reg_rtx (XFmode);
17269       rtx op1 = gen_reg_rtx (XFmode);
17271       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17272       emit_insn (gen_frndintxf2_floor (op0, op1));
17274       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17275     }
17276   DONE;
17279 (define_expand "floorsf2"
17280   [(use (match_operand:SF 0 "register_operand" ""))
17281    (use (match_operand:SF 1 "register_operand" ""))]
17282   "((TARGET_USE_FANCY_MATH_387
17283      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17284      && flag_unsafe_math_optimizations)
17285     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17286         && !flag_trapping_math))
17287    && !optimize_size"
17289   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17290       && !flag_trapping_math)
17291     ix86_expand_floorceil (operand0, operand1, true);
17292   else
17293     {
17294       rtx op0 = gen_reg_rtx (XFmode);
17295       rtx op1 = gen_reg_rtx (XFmode);
17297       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17298       emit_insn (gen_frndintxf2_floor (op0, op1));
17300       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17301     }
17302   DONE;
17305 (define_insn_and_split "*fist<mode>2_floor_1"
17306   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17307         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17308          UNSPEC_FIST_FLOOR))
17309    (clobber (reg:CC FLAGS_REG))]
17310   "TARGET_USE_FANCY_MATH_387
17311    && flag_unsafe_math_optimizations
17312    && !(reload_completed || reload_in_progress)"
17313   "#"
17314   "&& 1"
17315   [(const_int 0)]
17317   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17319   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17320   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17321   if (memory_operand (operands[0], VOIDmode))
17322     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17323                                       operands[2], operands[3]));
17324   else
17325     {
17326       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17327       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17328                                                   operands[2], operands[3],
17329                                                   operands[4]));
17330     }
17331   DONE;
17333   [(set_attr "type" "fistp")
17334    (set_attr "i387_cw" "floor")
17335    (set_attr "mode" "<MODE>")])
17337 (define_insn "fistdi2_floor"
17338   [(set (match_operand:DI 0 "memory_operand" "=m")
17339         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17340          UNSPEC_FIST_FLOOR))
17341    (use (match_operand:HI 2 "memory_operand" "m"))
17342    (use (match_operand:HI 3 "memory_operand" "m"))
17343    (clobber (match_scratch:XF 4 "=&1f"))]
17344   "TARGET_USE_FANCY_MATH_387
17345    && flag_unsafe_math_optimizations"
17346   "* return output_fix_trunc (insn, operands, 0);"
17347   [(set_attr "type" "fistp")
17348    (set_attr "i387_cw" "floor")
17349    (set_attr "mode" "DI")])
17351 (define_insn "fistdi2_floor_with_temp"
17352   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17353         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17354          UNSPEC_FIST_FLOOR))
17355    (use (match_operand:HI 2 "memory_operand" "m,m"))
17356    (use (match_operand:HI 3 "memory_operand" "m,m"))
17357    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17358    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17359   "TARGET_USE_FANCY_MATH_387
17360    && flag_unsafe_math_optimizations"
17361   "#"
17362   [(set_attr "type" "fistp")
17363    (set_attr "i387_cw" "floor")
17364    (set_attr "mode" "DI")])
17366 (define_split
17367   [(set (match_operand:DI 0 "register_operand" "")
17368         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17369          UNSPEC_FIST_FLOOR))
17370    (use (match_operand:HI 2 "memory_operand" ""))
17371    (use (match_operand:HI 3 "memory_operand" ""))
17372    (clobber (match_operand:DI 4 "memory_operand" ""))
17373    (clobber (match_scratch 5 ""))]
17374   "reload_completed"
17375   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17376               (use (match_dup 2))
17377               (use (match_dup 3))
17378               (clobber (match_dup 5))])
17379    (set (match_dup 0) (match_dup 4))]
17380   "")
17382 (define_split
17383   [(set (match_operand:DI 0 "memory_operand" "")
17384         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17385          UNSPEC_FIST_FLOOR))
17386    (use (match_operand:HI 2 "memory_operand" ""))
17387    (use (match_operand:HI 3 "memory_operand" ""))
17388    (clobber (match_operand:DI 4 "memory_operand" ""))
17389    (clobber (match_scratch 5 ""))]
17390   "reload_completed"
17391   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17392               (use (match_dup 2))
17393               (use (match_dup 3))
17394               (clobber (match_dup 5))])]
17395   "")
17397 (define_insn "fist<mode>2_floor"
17398   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17399         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17400          UNSPEC_FIST_FLOOR))
17401    (use (match_operand:HI 2 "memory_operand" "m"))
17402    (use (match_operand:HI 3 "memory_operand" "m"))]
17403   "TARGET_USE_FANCY_MATH_387
17404    && flag_unsafe_math_optimizations"
17405   "* return output_fix_trunc (insn, operands, 0);"
17406   [(set_attr "type" "fistp")
17407    (set_attr "i387_cw" "floor")
17408    (set_attr "mode" "<MODE>")])
17410 (define_insn "fist<mode>2_floor_with_temp"
17411   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17412         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17413          UNSPEC_FIST_FLOOR))
17414    (use (match_operand:HI 2 "memory_operand" "m,m"))
17415    (use (match_operand:HI 3 "memory_operand" "m,m"))
17416    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17417   "TARGET_USE_FANCY_MATH_387
17418    && flag_unsafe_math_optimizations"
17419   "#"
17420   [(set_attr "type" "fistp")
17421    (set_attr "i387_cw" "floor")
17422    (set_attr "mode" "<MODE>")])
17424 (define_split
17425   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17426         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17427          UNSPEC_FIST_FLOOR))
17428    (use (match_operand:HI 2 "memory_operand" ""))
17429    (use (match_operand:HI 3 "memory_operand" ""))
17430    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17431   "reload_completed"
17432   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17433                                   UNSPEC_FIST_FLOOR))
17434               (use (match_dup 2))
17435               (use (match_dup 3))])
17436    (set (match_dup 0) (match_dup 4))]
17437   "")
17439 (define_split
17440   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17441         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17442          UNSPEC_FIST_FLOOR))
17443    (use (match_operand:HI 2 "memory_operand" ""))
17444    (use (match_operand:HI 3 "memory_operand" ""))
17445    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17446   "reload_completed"
17447   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17448                                   UNSPEC_FIST_FLOOR))
17449               (use (match_dup 2))
17450               (use (match_dup 3))])]
17451   "")
17453 (define_expand "lfloorxf<mode>2"
17454   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17455                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17456                     UNSPEC_FIST_FLOOR))
17457               (clobber (reg:CC FLAGS_REG))])]
17458   "TARGET_USE_FANCY_MATH_387
17459    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17460    && flag_unsafe_math_optimizations"
17461   "")
17463 (define_expand "lfloor<mode>di2"
17464   [(match_operand:DI 0 "nonimmediate_operand" "")
17465    (match_operand:SSEMODEF 1 "register_operand" "")]
17466   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17467    && !flag_trapping_math
17468    && !optimize_size"
17470   ix86_expand_lfloorceil (operand0, operand1, true);
17471   DONE;
17474 (define_expand "lfloor<mode>si2"
17475   [(match_operand:SI 0 "nonimmediate_operand" "")
17476    (match_operand:SSEMODEF 1 "register_operand" "")]
17477   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17478    && !flag_trapping_math
17479    && (!optimize_size || !TARGET_64BIT)"
17481   ix86_expand_lfloorceil (operand0, operand1, true);
17482   DONE;
17485 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17486 (define_insn_and_split "frndintxf2_ceil"
17487   [(set (match_operand:XF 0 "register_operand" "=f")
17488         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17489          UNSPEC_FRNDINT_CEIL))
17490    (clobber (reg:CC FLAGS_REG))]
17491   "TARGET_USE_FANCY_MATH_387
17492    && flag_unsafe_math_optimizations
17493    && !(reload_completed || reload_in_progress)"
17494   "#"
17495   "&& 1"
17496   [(const_int 0)]
17498   ix86_optimize_mode_switching[I387_CEIL] = 1;
17500   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17501   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17503   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17504                                        operands[2], operands[3]));
17505   DONE;
17507   [(set_attr "type" "frndint")
17508    (set_attr "i387_cw" "ceil")
17509    (set_attr "mode" "XF")])
17511 (define_insn "frndintxf2_ceil_i387"
17512   [(set (match_operand:XF 0 "register_operand" "=f")
17513         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17514          UNSPEC_FRNDINT_CEIL))
17515    (use (match_operand:HI 2 "memory_operand" "m"))
17516    (use (match_operand:HI 3 "memory_operand" "m"))]
17517   "TARGET_USE_FANCY_MATH_387
17518    && flag_unsafe_math_optimizations"
17519   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17520   [(set_attr "type" "frndint")
17521    (set_attr "i387_cw" "ceil")
17522    (set_attr "mode" "XF")])
17524 (define_expand "ceilxf2"
17525   [(use (match_operand:XF 0 "register_operand" ""))
17526    (use (match_operand:XF 1 "register_operand" ""))]
17527   "TARGET_USE_FANCY_MATH_387
17528    && flag_unsafe_math_optimizations && !optimize_size"
17530   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17531   DONE;
17534 (define_expand "ceildf2"
17535   [(use (match_operand:DF 0 "register_operand" ""))
17536    (use (match_operand:DF 1 "register_operand" ""))]
17537   "((TARGET_USE_FANCY_MATH_387
17538      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17539      && flag_unsafe_math_optimizations)
17540     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17541         && !flag_trapping_math))
17542    && !optimize_size"
17544   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17545       && !flag_trapping_math)
17546     {
17547       if (TARGET_64BIT)
17548         ix86_expand_floorceil (operand0, operand1, false);
17549       else
17550         ix86_expand_floorceildf_32 (operand0, operand1, false);
17551     }
17552   else
17553     {
17554       rtx op0 = gen_reg_rtx (XFmode);
17555       rtx op1 = gen_reg_rtx (XFmode);
17557       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17558       emit_insn (gen_frndintxf2_ceil (op0, op1));
17560       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17561     }
17562   DONE;
17565 (define_expand "ceilsf2"
17566   [(use (match_operand:SF 0 "register_operand" ""))
17567    (use (match_operand:SF 1 "register_operand" ""))]
17568   "((TARGET_USE_FANCY_MATH_387
17569      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17570      && flag_unsafe_math_optimizations)
17571     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17572         && !flag_trapping_math))
17573    && !optimize_size"
17575   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17576       && !flag_trapping_math)
17577     ix86_expand_floorceil (operand0, operand1, false);
17578   else
17579     {
17580       rtx op0 = gen_reg_rtx (XFmode);
17581       rtx op1 = gen_reg_rtx (XFmode);
17583       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17584       emit_insn (gen_frndintxf2_ceil (op0, op1));
17586       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17587     }
17588   DONE;
17591 (define_insn_and_split "*fist<mode>2_ceil_1"
17592   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17593         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17594          UNSPEC_FIST_CEIL))
17595    (clobber (reg:CC FLAGS_REG))]
17596   "TARGET_USE_FANCY_MATH_387
17597    && flag_unsafe_math_optimizations
17598    && !(reload_completed || reload_in_progress)"
17599   "#"
17600   "&& 1"
17601   [(const_int 0)]
17603   ix86_optimize_mode_switching[I387_CEIL] = 1;
17605   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17606   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17607   if (memory_operand (operands[0], VOIDmode))
17608     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17609                                      operands[2], operands[3]));
17610   else
17611     {
17612       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17613       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17614                                                  operands[2], operands[3],
17615                                                  operands[4]));
17616     }
17617   DONE;
17619   [(set_attr "type" "fistp")
17620    (set_attr "i387_cw" "ceil")
17621    (set_attr "mode" "<MODE>")])
17623 (define_insn "fistdi2_ceil"
17624   [(set (match_operand:DI 0 "memory_operand" "=m")
17625         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17626          UNSPEC_FIST_CEIL))
17627    (use (match_operand:HI 2 "memory_operand" "m"))
17628    (use (match_operand:HI 3 "memory_operand" "m"))
17629    (clobber (match_scratch:XF 4 "=&1f"))]
17630   "TARGET_USE_FANCY_MATH_387
17631    && flag_unsafe_math_optimizations"
17632   "* return output_fix_trunc (insn, operands, 0);"
17633   [(set_attr "type" "fistp")
17634    (set_attr "i387_cw" "ceil")
17635    (set_attr "mode" "DI")])
17637 (define_insn "fistdi2_ceil_with_temp"
17638   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17639         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17640          UNSPEC_FIST_CEIL))
17641    (use (match_operand:HI 2 "memory_operand" "m,m"))
17642    (use (match_operand:HI 3 "memory_operand" "m,m"))
17643    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17644    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17645   "TARGET_USE_FANCY_MATH_387
17646    && flag_unsafe_math_optimizations"
17647   "#"
17648   [(set_attr "type" "fistp")
17649    (set_attr "i387_cw" "ceil")
17650    (set_attr "mode" "DI")])
17652 (define_split
17653   [(set (match_operand:DI 0 "register_operand" "")
17654         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17655          UNSPEC_FIST_CEIL))
17656    (use (match_operand:HI 2 "memory_operand" ""))
17657    (use (match_operand:HI 3 "memory_operand" ""))
17658    (clobber (match_operand:DI 4 "memory_operand" ""))
17659    (clobber (match_scratch 5 ""))]
17660   "reload_completed"
17661   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17662               (use (match_dup 2))
17663               (use (match_dup 3))
17664               (clobber (match_dup 5))])
17665    (set (match_dup 0) (match_dup 4))]
17666   "")
17668 (define_split
17669   [(set (match_operand:DI 0 "memory_operand" "")
17670         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17671          UNSPEC_FIST_CEIL))
17672    (use (match_operand:HI 2 "memory_operand" ""))
17673    (use (match_operand:HI 3 "memory_operand" ""))
17674    (clobber (match_operand:DI 4 "memory_operand" ""))
17675    (clobber (match_scratch 5 ""))]
17676   "reload_completed"
17677   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17678               (use (match_dup 2))
17679               (use (match_dup 3))
17680               (clobber (match_dup 5))])]
17681   "")
17683 (define_insn "fist<mode>2_ceil"
17684   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17685         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17686          UNSPEC_FIST_CEIL))
17687    (use (match_operand:HI 2 "memory_operand" "m"))
17688    (use (match_operand:HI 3 "memory_operand" "m"))]
17689   "TARGET_USE_FANCY_MATH_387
17690    && flag_unsafe_math_optimizations"
17691   "* return output_fix_trunc (insn, operands, 0);"
17692   [(set_attr "type" "fistp")
17693    (set_attr "i387_cw" "ceil")
17694    (set_attr "mode" "<MODE>")])
17696 (define_insn "fist<mode>2_ceil_with_temp"
17697   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17698         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17699          UNSPEC_FIST_CEIL))
17700    (use (match_operand:HI 2 "memory_operand" "m,m"))
17701    (use (match_operand:HI 3 "memory_operand" "m,m"))
17702    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17703   "TARGET_USE_FANCY_MATH_387
17704    && flag_unsafe_math_optimizations"
17705   "#"
17706   [(set_attr "type" "fistp")
17707    (set_attr "i387_cw" "ceil")
17708    (set_attr "mode" "<MODE>")])
17710 (define_split
17711   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17712         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17713          UNSPEC_FIST_CEIL))
17714    (use (match_operand:HI 2 "memory_operand" ""))
17715    (use (match_operand:HI 3 "memory_operand" ""))
17716    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17717   "reload_completed"
17718   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17719                                   UNSPEC_FIST_CEIL))
17720               (use (match_dup 2))
17721               (use (match_dup 3))])
17722    (set (match_dup 0) (match_dup 4))]
17723   "")
17725 (define_split
17726   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17727         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17728          UNSPEC_FIST_CEIL))
17729    (use (match_operand:HI 2 "memory_operand" ""))
17730    (use (match_operand:HI 3 "memory_operand" ""))
17731    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17732   "reload_completed"
17733   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17734                                   UNSPEC_FIST_CEIL))
17735               (use (match_dup 2))
17736               (use (match_dup 3))])]
17737   "")
17739 (define_expand "lceilxf<mode>2"
17740   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17741                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17742                     UNSPEC_FIST_CEIL))
17743               (clobber (reg:CC FLAGS_REG))])]
17744   "TARGET_USE_FANCY_MATH_387
17745    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17746    && flag_unsafe_math_optimizations"
17747   "")
17749 (define_expand "lceil<mode>di2"
17750   [(match_operand:DI 0 "nonimmediate_operand" "")
17751    (match_operand:SSEMODEF 1 "register_operand" "")]
17752   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17753    && !flag_trapping_math"
17755   ix86_expand_lfloorceil (operand0, operand1, false);
17756   DONE;
17759 (define_expand "lceil<mode>si2"
17760   [(match_operand:SI 0 "nonimmediate_operand" "")
17761    (match_operand:SSEMODEF 1 "register_operand" "")]
17762   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17763    && !flag_trapping_math"
17765   ix86_expand_lfloorceil (operand0, operand1, false);
17766   DONE;
17769 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17770 (define_insn_and_split "frndintxf2_trunc"
17771   [(set (match_operand:XF 0 "register_operand" "=f")
17772         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17773          UNSPEC_FRNDINT_TRUNC))
17774    (clobber (reg:CC FLAGS_REG))]
17775   "TARGET_USE_FANCY_MATH_387
17776    && flag_unsafe_math_optimizations
17777    && !(reload_completed || reload_in_progress)"
17778   "#"
17779   "&& 1"
17780   [(const_int 0)]
17782   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17784   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17785   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17787   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17788                                         operands[2], operands[3]));
17789   DONE;
17791   [(set_attr "type" "frndint")
17792    (set_attr "i387_cw" "trunc")
17793    (set_attr "mode" "XF")])
17795 (define_insn "frndintxf2_trunc_i387"
17796   [(set (match_operand:XF 0 "register_operand" "=f")
17797         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17798          UNSPEC_FRNDINT_TRUNC))
17799    (use (match_operand:HI 2 "memory_operand" "m"))
17800    (use (match_operand:HI 3 "memory_operand" "m"))]
17801   "TARGET_USE_FANCY_MATH_387
17802    && flag_unsafe_math_optimizations"
17803   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17804   [(set_attr "type" "frndint")
17805    (set_attr "i387_cw" "trunc")
17806    (set_attr "mode" "XF")])
17808 (define_expand "btruncxf2"
17809   [(use (match_operand:XF 0 "register_operand" ""))
17810    (use (match_operand:XF 1 "register_operand" ""))]
17811   "TARGET_USE_FANCY_MATH_387
17812    && flag_unsafe_math_optimizations && !optimize_size"
17814   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17815   DONE;
17818 (define_expand "btruncdf2"
17819   [(use (match_operand:DF 0 "register_operand" ""))
17820    (use (match_operand:DF 1 "register_operand" ""))]
17821   "((TARGET_USE_FANCY_MATH_387
17822      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17823      && flag_unsafe_math_optimizations)
17824     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17825         && !flag_trapping_math))
17826    && !optimize_size"
17828   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17829       && !flag_trapping_math)
17830     {
17831       if (TARGET_64BIT)
17832         ix86_expand_trunc (operand0, operand1);
17833       else
17834         ix86_expand_truncdf_32 (operand0, operand1);
17835     }
17836   else
17837     {
17838       rtx op0 = gen_reg_rtx (XFmode);
17839       rtx op1 = gen_reg_rtx (XFmode);
17841       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17842       emit_insn (gen_frndintxf2_trunc (op0, op1));
17844       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17845     }
17846   DONE;
17849 (define_expand "btruncsf2"
17850   [(use (match_operand:SF 0 "register_operand" ""))
17851    (use (match_operand:SF 1 "register_operand" ""))]
17852   "((TARGET_USE_FANCY_MATH_387
17853      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17854      && flag_unsafe_math_optimizations)
17855     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17856         && !flag_trapping_math))
17857    && !optimize_size"
17859   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17860       && !flag_trapping_math)
17861     ix86_expand_trunc (operand0, operand1);
17862   else
17863     {
17864       rtx op0 = gen_reg_rtx (XFmode);
17865       rtx op1 = gen_reg_rtx (XFmode);
17867       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17868       emit_insn (gen_frndintxf2_trunc (op0, op1));
17870       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17871     }
17872   DONE;
17875 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17876 (define_insn_and_split "frndintxf2_mask_pm"
17877   [(set (match_operand:XF 0 "register_operand" "=f")
17878         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17879          UNSPEC_FRNDINT_MASK_PM))
17880    (clobber (reg:CC FLAGS_REG))]
17881   "TARGET_USE_FANCY_MATH_387
17882    && flag_unsafe_math_optimizations
17883    && !(reload_completed || reload_in_progress)"
17884   "#"
17885   "&& 1"
17886   [(const_int 0)]
17888   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17890   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17891   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17893   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17894                                           operands[2], operands[3]));
17895   DONE;
17897   [(set_attr "type" "frndint")
17898    (set_attr "i387_cw" "mask_pm")
17899    (set_attr "mode" "XF")])
17901 (define_insn "frndintxf2_mask_pm_i387"
17902   [(set (match_operand:XF 0 "register_operand" "=f")
17903         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17904          UNSPEC_FRNDINT_MASK_PM))
17905    (use (match_operand:HI 2 "memory_operand" "m"))
17906    (use (match_operand:HI 3 "memory_operand" "m"))]
17907   "TARGET_USE_FANCY_MATH_387
17908    && flag_unsafe_math_optimizations"
17909   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17910   [(set_attr "type" "frndint")
17911    (set_attr "i387_cw" "mask_pm")
17912    (set_attr "mode" "XF")])
17914 (define_expand "nearbyintxf2"
17915   [(use (match_operand:XF 0 "register_operand" ""))
17916    (use (match_operand:XF 1 "register_operand" ""))]
17917   "TARGET_USE_FANCY_MATH_387
17918    && flag_unsafe_math_optimizations"
17920   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17922   DONE;
17925 (define_expand "nearbyintdf2"
17926   [(use (match_operand:DF 0 "register_operand" ""))
17927    (use (match_operand:DF 1 "register_operand" ""))]
17928   "TARGET_USE_FANCY_MATH_387
17929    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17930    && flag_unsafe_math_optimizations"
17932   rtx op0 = gen_reg_rtx (XFmode);
17933   rtx op1 = gen_reg_rtx (XFmode);
17935   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17936   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17938   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17939   DONE;
17942 (define_expand "nearbyintsf2"
17943   [(use (match_operand:SF 0 "register_operand" ""))
17944    (use (match_operand:SF 1 "register_operand" ""))]
17945   "TARGET_USE_FANCY_MATH_387
17946    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17947    && flag_unsafe_math_optimizations"
17949   rtx op0 = gen_reg_rtx (XFmode);
17950   rtx op1 = gen_reg_rtx (XFmode);
17952   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17953   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17955   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17956   DONE;
17959 (define_insn "fxam<mode>2_i387"
17960   [(set (match_operand:HI 0 "register_operand" "=a")
17961         (unspec:HI
17962           [(match_operand:X87MODEF 1 "register_operand" "f")]
17963           UNSPEC_FXAM))]
17964   "TARGET_USE_FANCY_MATH_387"
17965   "fxam\n\tfnstsw\t%0"
17966   [(set_attr "type" "multi")
17967    (set_attr "unit" "i387")
17968    (set_attr "mode" "<MODE>")])
17970 (define_expand "isinf<mode>2"
17971   [(use (match_operand:SI 0 "register_operand" ""))
17972    (use (match_operand:X87MODEF 1 "register_operand" ""))]
17973   "TARGET_USE_FANCY_MATH_387
17974    && TARGET_C99_FUNCTIONS
17975    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17976        || TARGET_MIX_SSE_I387)"
17978   rtx mask = GEN_INT (0x45);
17979   rtx val = GEN_INT (0x05);
17981   rtx cond;
17983   rtx scratch = gen_reg_rtx (HImode);
17984   rtx res = gen_reg_rtx (QImode);
17986   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17987   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17988   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17989   cond = gen_rtx_fmt_ee (EQ, QImode,
17990                          gen_rtx_REG (CCmode, FLAGS_REG),
17991                          const0_rtx);
17992   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17993   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17994   DONE;
17998 ;; Block operation instructions
18000 (define_expand "movmemsi"
18001   [(use (match_operand:BLK 0 "memory_operand" ""))
18002    (use (match_operand:BLK 1 "memory_operand" ""))
18003    (use (match_operand:SI 2 "nonmemory_operand" ""))
18004    (use (match_operand:SI 3 "const_int_operand" ""))
18005    (use (match_operand:SI 4 "const_int_operand" ""))
18006    (use (match_operand:SI 5 "const_int_operand" ""))]
18007   ""
18009  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18010                          operands[4], operands[5]))
18011    DONE;
18012  else
18013    FAIL;
18016 (define_expand "movmemdi"
18017   [(use (match_operand:BLK 0 "memory_operand" ""))
18018    (use (match_operand:BLK 1 "memory_operand" ""))
18019    (use (match_operand:DI 2 "nonmemory_operand" ""))
18020    (use (match_operand:DI 3 "const_int_operand" ""))
18021    (use (match_operand:SI 4 "const_int_operand" ""))
18022    (use (match_operand:SI 5 "const_int_operand" ""))]
18023   "TARGET_64BIT"
18025  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18026                          operands[4], operands[5]))
18027    DONE;
18028  else
18029    FAIL;
18032 ;; Most CPUs don't like single string operations
18033 ;; Handle this case here to simplify previous expander.
18035 (define_expand "strmov"
18036   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18037    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18038    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18039               (clobber (reg:CC FLAGS_REG))])
18040    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18041               (clobber (reg:CC FLAGS_REG))])]
18042   ""
18044   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18046   /* If .md ever supports :P for Pmode, these can be directly
18047      in the pattern above.  */
18048   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18049   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18051   if (TARGET_SINGLE_STRINGOP || optimize_size)
18052     {
18053       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18054                                       operands[2], operands[3],
18055                                       operands[5], operands[6]));
18056       DONE;
18057     }
18059   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18062 (define_expand "strmov_singleop"
18063   [(parallel [(set (match_operand 1 "memory_operand" "")
18064                    (match_operand 3 "memory_operand" ""))
18065               (set (match_operand 0 "register_operand" "")
18066                    (match_operand 4 "" ""))
18067               (set (match_operand 2 "register_operand" "")
18068                    (match_operand 5 "" ""))])]
18069   "TARGET_SINGLE_STRINGOP || optimize_size"
18070   "")
18072 (define_insn "*strmovdi_rex_1"
18073   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18074         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18075    (set (match_operand:DI 0 "register_operand" "=D")
18076         (plus:DI (match_dup 2)
18077                  (const_int 8)))
18078    (set (match_operand:DI 1 "register_operand" "=S")
18079         (plus:DI (match_dup 3)
18080                  (const_int 8)))]
18081   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18082   "movsq"
18083   [(set_attr "type" "str")
18084    (set_attr "mode" "DI")
18085    (set_attr "memory" "both")])
18087 (define_insn "*strmovsi_1"
18088   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18089         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18090    (set (match_operand:SI 0 "register_operand" "=D")
18091         (plus:SI (match_dup 2)
18092                  (const_int 4)))
18093    (set (match_operand:SI 1 "register_operand" "=S")
18094         (plus:SI (match_dup 3)
18095                  (const_int 4)))]
18096   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18097   "{movsl|movsd}"
18098   [(set_attr "type" "str")
18099    (set_attr "mode" "SI")
18100    (set_attr "memory" "both")])
18102 (define_insn "*strmovsi_rex_1"
18103   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18104         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18105    (set (match_operand:DI 0 "register_operand" "=D")
18106         (plus:DI (match_dup 2)
18107                  (const_int 4)))
18108    (set (match_operand:DI 1 "register_operand" "=S")
18109         (plus:DI (match_dup 3)
18110                  (const_int 4)))]
18111   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18112   "{movsl|movsd}"
18113   [(set_attr "type" "str")
18114    (set_attr "mode" "SI")
18115    (set_attr "memory" "both")])
18117 (define_insn "*strmovhi_1"
18118   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18119         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18120    (set (match_operand:SI 0 "register_operand" "=D")
18121         (plus:SI (match_dup 2)
18122                  (const_int 2)))
18123    (set (match_operand:SI 1 "register_operand" "=S")
18124         (plus:SI (match_dup 3)
18125                  (const_int 2)))]
18126   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18127   "movsw"
18128   [(set_attr "type" "str")
18129    (set_attr "memory" "both")
18130    (set_attr "mode" "HI")])
18132 (define_insn "*strmovhi_rex_1"
18133   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18134         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18135    (set (match_operand:DI 0 "register_operand" "=D")
18136         (plus:DI (match_dup 2)
18137                  (const_int 2)))
18138    (set (match_operand:DI 1 "register_operand" "=S")
18139         (plus:DI (match_dup 3)
18140                  (const_int 2)))]
18141   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18142   "movsw"
18143   [(set_attr "type" "str")
18144    (set_attr "memory" "both")
18145    (set_attr "mode" "HI")])
18147 (define_insn "*strmovqi_1"
18148   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18149         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18150    (set (match_operand:SI 0 "register_operand" "=D")
18151         (plus:SI (match_dup 2)
18152                  (const_int 1)))
18153    (set (match_operand:SI 1 "register_operand" "=S")
18154         (plus:SI (match_dup 3)
18155                  (const_int 1)))]
18156   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18157   "movsb"
18158   [(set_attr "type" "str")
18159    (set_attr "memory" "both")
18160    (set_attr "mode" "QI")])
18162 (define_insn "*strmovqi_rex_1"
18163   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18164         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18165    (set (match_operand:DI 0 "register_operand" "=D")
18166         (plus:DI (match_dup 2)
18167                  (const_int 1)))
18168    (set (match_operand:DI 1 "register_operand" "=S")
18169         (plus:DI (match_dup 3)
18170                  (const_int 1)))]
18171   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18172   "movsb"
18173   [(set_attr "type" "str")
18174    (set_attr "memory" "both")
18175    (set_attr "mode" "QI")])
18177 (define_expand "rep_mov"
18178   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18179               (set (match_operand 0 "register_operand" "")
18180                    (match_operand 5 "" ""))
18181               (set (match_operand 2 "register_operand" "")
18182                    (match_operand 6 "" ""))
18183               (set (match_operand 1 "memory_operand" "")
18184                    (match_operand 3 "memory_operand" ""))
18185               (use (match_dup 4))])]
18186   ""
18187   "")
18189 (define_insn "*rep_movdi_rex64"
18190   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18191    (set (match_operand:DI 0 "register_operand" "=D")
18192         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18193                             (const_int 3))
18194                  (match_operand:DI 3 "register_operand" "0")))
18195    (set (match_operand:DI 1 "register_operand" "=S")
18196         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18197                  (match_operand:DI 4 "register_operand" "1")))
18198    (set (mem:BLK (match_dup 3))
18199         (mem:BLK (match_dup 4)))
18200    (use (match_dup 5))]
18201   "TARGET_64BIT"
18202   "{rep\;movsq|rep movsq}"
18203   [(set_attr "type" "str")
18204    (set_attr "prefix_rep" "1")
18205    (set_attr "memory" "both")
18206    (set_attr "mode" "DI")])
18208 (define_insn "*rep_movsi"
18209   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18210    (set (match_operand:SI 0 "register_operand" "=D")
18211         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18212                             (const_int 2))
18213                  (match_operand:SI 3 "register_operand" "0")))
18214    (set (match_operand:SI 1 "register_operand" "=S")
18215         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18216                  (match_operand:SI 4 "register_operand" "1")))
18217    (set (mem:BLK (match_dup 3))
18218         (mem:BLK (match_dup 4)))
18219    (use (match_dup 5))]
18220   "!TARGET_64BIT"
18221   "{rep\;movsl|rep movsd}"
18222   [(set_attr "type" "str")
18223    (set_attr "prefix_rep" "1")
18224    (set_attr "memory" "both")
18225    (set_attr "mode" "SI")])
18227 (define_insn "*rep_movsi_rex64"
18228   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18229    (set (match_operand:DI 0 "register_operand" "=D")
18230         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18231                             (const_int 2))
18232                  (match_operand:DI 3 "register_operand" "0")))
18233    (set (match_operand:DI 1 "register_operand" "=S")
18234         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18235                  (match_operand:DI 4 "register_operand" "1")))
18236    (set (mem:BLK (match_dup 3))
18237         (mem:BLK (match_dup 4)))
18238    (use (match_dup 5))]
18239   "TARGET_64BIT"
18240   "{rep\;movsl|rep movsd}"
18241   [(set_attr "type" "str")
18242    (set_attr "prefix_rep" "1")
18243    (set_attr "memory" "both")
18244    (set_attr "mode" "SI")])
18246 (define_insn "*rep_movqi"
18247   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18248    (set (match_operand:SI 0 "register_operand" "=D")
18249         (plus:SI (match_operand:SI 3 "register_operand" "0")
18250                  (match_operand:SI 5 "register_operand" "2")))
18251    (set (match_operand:SI 1 "register_operand" "=S")
18252         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18253    (set (mem:BLK (match_dup 3))
18254         (mem:BLK (match_dup 4)))
18255    (use (match_dup 5))]
18256   "!TARGET_64BIT"
18257   "{rep\;movsb|rep movsb}"
18258   [(set_attr "type" "str")
18259    (set_attr "prefix_rep" "1")
18260    (set_attr "memory" "both")
18261    (set_attr "mode" "SI")])
18263 (define_insn "*rep_movqi_rex64"
18264   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18265    (set (match_operand:DI 0 "register_operand" "=D")
18266         (plus:DI (match_operand:DI 3 "register_operand" "0")
18267                  (match_operand:DI 5 "register_operand" "2")))
18268    (set (match_operand:DI 1 "register_operand" "=S")
18269         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18270    (set (mem:BLK (match_dup 3))
18271         (mem:BLK (match_dup 4)))
18272    (use (match_dup 5))]
18273   "TARGET_64BIT"
18274   "{rep\;movsb|rep movsb}"
18275   [(set_attr "type" "str")
18276    (set_attr "prefix_rep" "1")
18277    (set_attr "memory" "both")
18278    (set_attr "mode" "SI")])
18280 (define_expand "setmemsi"
18281    [(use (match_operand:BLK 0 "memory_operand" ""))
18282     (use (match_operand:SI 1 "nonmemory_operand" ""))
18283     (use (match_operand 2 "const_int_operand" ""))
18284     (use (match_operand 3 "const_int_operand" ""))
18285     (use (match_operand:SI 4 "const_int_operand" ""))
18286     (use (match_operand:SI 5 "const_int_operand" ""))]
18287   ""
18289  if (ix86_expand_setmem (operands[0], operands[1],
18290                          operands[2], operands[3],
18291                          operands[4], operands[5]))
18292    DONE;
18293  else
18294    FAIL;
18297 (define_expand "setmemdi"
18298    [(use (match_operand:BLK 0 "memory_operand" ""))
18299     (use (match_operand:DI 1 "nonmemory_operand" ""))
18300     (use (match_operand 2 "const_int_operand" ""))
18301     (use (match_operand 3 "const_int_operand" ""))
18302     (use (match_operand 4 "const_int_operand" ""))
18303     (use (match_operand 5 "const_int_operand" ""))]
18304   "TARGET_64BIT"
18306  if (ix86_expand_setmem (operands[0], operands[1],
18307                          operands[2], operands[3],
18308                          operands[4], operands[5]))
18309    DONE;
18310  else
18311    FAIL;
18314 ;; Most CPUs don't like single string operations
18315 ;; Handle this case here to simplify previous expander.
18317 (define_expand "strset"
18318   [(set (match_operand 1 "memory_operand" "")
18319         (match_operand 2 "register_operand" ""))
18320    (parallel [(set (match_operand 0 "register_operand" "")
18321                    (match_dup 3))
18322               (clobber (reg:CC FLAGS_REG))])]
18323   ""
18325   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18326     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18328   /* If .md ever supports :P for Pmode, this can be directly
18329      in the pattern above.  */
18330   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18331                               GEN_INT (GET_MODE_SIZE (GET_MODE
18332                                                       (operands[2]))));
18333   if (TARGET_SINGLE_STRINGOP || optimize_size)
18334     {
18335       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18336                                       operands[3]));
18337       DONE;
18338     }
18341 (define_expand "strset_singleop"
18342   [(parallel [(set (match_operand 1 "memory_operand" "")
18343                    (match_operand 2 "register_operand" ""))
18344               (set (match_operand 0 "register_operand" "")
18345                    (match_operand 3 "" ""))])]
18346   "TARGET_SINGLE_STRINGOP || optimize_size"
18347   "")
18349 (define_insn "*strsetdi_rex_1"
18350   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18351         (match_operand:DI 2 "register_operand" "a"))
18352    (set (match_operand:DI 0 "register_operand" "=D")
18353         (plus:DI (match_dup 1)
18354                  (const_int 8)))]
18355   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18356   "stosq"
18357   [(set_attr "type" "str")
18358    (set_attr "memory" "store")
18359    (set_attr "mode" "DI")])
18361 (define_insn "*strsetsi_1"
18362   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18363         (match_operand:SI 2 "register_operand" "a"))
18364    (set (match_operand:SI 0 "register_operand" "=D")
18365         (plus:SI (match_dup 1)
18366                  (const_int 4)))]
18367   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18368   "{stosl|stosd}"
18369   [(set_attr "type" "str")
18370    (set_attr "memory" "store")
18371    (set_attr "mode" "SI")])
18373 (define_insn "*strsetsi_rex_1"
18374   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18375         (match_operand:SI 2 "register_operand" "a"))
18376    (set (match_operand:DI 0 "register_operand" "=D")
18377         (plus:DI (match_dup 1)
18378                  (const_int 4)))]
18379   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18380   "{stosl|stosd}"
18381   [(set_attr "type" "str")
18382    (set_attr "memory" "store")
18383    (set_attr "mode" "SI")])
18385 (define_insn "*strsethi_1"
18386   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18387         (match_operand:HI 2 "register_operand" "a"))
18388    (set (match_operand:SI 0 "register_operand" "=D")
18389         (plus:SI (match_dup 1)
18390                  (const_int 2)))]
18391   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18392   "stosw"
18393   [(set_attr "type" "str")
18394    (set_attr "memory" "store")
18395    (set_attr "mode" "HI")])
18397 (define_insn "*strsethi_rex_1"
18398   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18399         (match_operand:HI 2 "register_operand" "a"))
18400    (set (match_operand:DI 0 "register_operand" "=D")
18401         (plus:DI (match_dup 1)
18402                  (const_int 2)))]
18403   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18404   "stosw"
18405   [(set_attr "type" "str")
18406    (set_attr "memory" "store")
18407    (set_attr "mode" "HI")])
18409 (define_insn "*strsetqi_1"
18410   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18411         (match_operand:QI 2 "register_operand" "a"))
18412    (set (match_operand:SI 0 "register_operand" "=D")
18413         (plus:SI (match_dup 1)
18414                  (const_int 1)))]
18415   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18416   "stosb"
18417   [(set_attr "type" "str")
18418    (set_attr "memory" "store")
18419    (set_attr "mode" "QI")])
18421 (define_insn "*strsetqi_rex_1"
18422   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18423         (match_operand:QI 2 "register_operand" "a"))
18424    (set (match_operand:DI 0 "register_operand" "=D")
18425         (plus:DI (match_dup 1)
18426                  (const_int 1)))]
18427   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18428   "stosb"
18429   [(set_attr "type" "str")
18430    (set_attr "memory" "store")
18431    (set_attr "mode" "QI")])
18433 (define_expand "rep_stos"
18434   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18435               (set (match_operand 0 "register_operand" "")
18436                    (match_operand 4 "" ""))
18437               (set (match_operand 2 "memory_operand" "") (const_int 0))
18438               (use (match_operand 3 "register_operand" ""))
18439               (use (match_dup 1))])]
18440   ""
18441   "")
18443 (define_insn "*rep_stosdi_rex64"
18444   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18445    (set (match_operand:DI 0 "register_operand" "=D")
18446         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18447                             (const_int 3))
18448                  (match_operand:DI 3 "register_operand" "0")))
18449    (set (mem:BLK (match_dup 3))
18450         (const_int 0))
18451    (use (match_operand:DI 2 "register_operand" "a"))
18452    (use (match_dup 4))]
18453   "TARGET_64BIT"
18454   "{rep\;stosq|rep stosq}"
18455   [(set_attr "type" "str")
18456    (set_attr "prefix_rep" "1")
18457    (set_attr "memory" "store")
18458    (set_attr "mode" "DI")])
18460 (define_insn "*rep_stossi"
18461   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18462    (set (match_operand:SI 0 "register_operand" "=D")
18463         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18464                             (const_int 2))
18465                  (match_operand:SI 3 "register_operand" "0")))
18466    (set (mem:BLK (match_dup 3))
18467         (const_int 0))
18468    (use (match_operand:SI 2 "register_operand" "a"))
18469    (use (match_dup 4))]
18470   "!TARGET_64BIT"
18471   "{rep\;stosl|rep stosd}"
18472   [(set_attr "type" "str")
18473    (set_attr "prefix_rep" "1")
18474    (set_attr "memory" "store")
18475    (set_attr "mode" "SI")])
18477 (define_insn "*rep_stossi_rex64"
18478   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18479    (set (match_operand:DI 0 "register_operand" "=D")
18480         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18481                             (const_int 2))
18482                  (match_operand:DI 3 "register_operand" "0")))
18483    (set (mem:BLK (match_dup 3))
18484         (const_int 0))
18485    (use (match_operand:SI 2 "register_operand" "a"))
18486    (use (match_dup 4))]
18487   "TARGET_64BIT"
18488   "{rep\;stosl|rep stosd}"
18489   [(set_attr "type" "str")
18490    (set_attr "prefix_rep" "1")
18491    (set_attr "memory" "store")
18492    (set_attr "mode" "SI")])
18494 (define_insn "*rep_stosqi"
18495   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18496    (set (match_operand:SI 0 "register_operand" "=D")
18497         (plus:SI (match_operand:SI 3 "register_operand" "0")
18498                  (match_operand:SI 4 "register_operand" "1")))
18499    (set (mem:BLK (match_dup 3))
18500         (const_int 0))
18501    (use (match_operand:QI 2 "register_operand" "a"))
18502    (use (match_dup 4))]
18503   "!TARGET_64BIT"
18504   "{rep\;stosb|rep stosb}"
18505   [(set_attr "type" "str")
18506    (set_attr "prefix_rep" "1")
18507    (set_attr "memory" "store")
18508    (set_attr "mode" "QI")])
18510 (define_insn "*rep_stosqi_rex64"
18511   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18512    (set (match_operand:DI 0 "register_operand" "=D")
18513         (plus:DI (match_operand:DI 3 "register_operand" "0")
18514                  (match_operand:DI 4 "register_operand" "1")))
18515    (set (mem:BLK (match_dup 3))
18516         (const_int 0))
18517    (use (match_operand:QI 2 "register_operand" "a"))
18518    (use (match_dup 4))]
18519   "TARGET_64BIT"
18520   "{rep\;stosb|rep stosb}"
18521   [(set_attr "type" "str")
18522    (set_attr "prefix_rep" "1")
18523    (set_attr "memory" "store")
18524    (set_attr "mode" "QI")])
18526 (define_expand "cmpstrnsi"
18527   [(set (match_operand:SI 0 "register_operand" "")
18528         (compare:SI (match_operand:BLK 1 "general_operand" "")
18529                     (match_operand:BLK 2 "general_operand" "")))
18530    (use (match_operand 3 "general_operand" ""))
18531    (use (match_operand 4 "immediate_operand" ""))]
18532   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18534   rtx addr1, addr2, out, outlow, count, countreg, align;
18536   /* Can't use this if the user has appropriated esi or edi.  */
18537   if (global_regs[4] || global_regs[5])
18538     FAIL;
18540   out = operands[0];
18541   if (!REG_P (out))
18542     out = gen_reg_rtx (SImode);
18544   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18545   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18546   if (addr1 != XEXP (operands[1], 0))
18547     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18548   if (addr2 != XEXP (operands[2], 0))
18549     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18551   count = operands[3];
18552   countreg = ix86_zero_extend_to_Pmode (count);
18554   /* %%% Iff we are testing strict equality, we can use known alignment
18555      to good advantage.  This may be possible with combine, particularly
18556      once cc0 is dead.  */
18557   align = operands[4];
18559   if (CONST_INT_P (count))
18560     {
18561       if (INTVAL (count) == 0)
18562         {
18563           emit_move_insn (operands[0], const0_rtx);
18564           DONE;
18565         }
18566       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18567                                      operands[1], operands[2]));
18568     }
18569   else
18570     {
18571       if (TARGET_64BIT)
18572         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18573       else
18574         emit_insn (gen_cmpsi_1 (countreg, countreg));
18575       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18576                                   operands[1], operands[2]));
18577     }
18579   outlow = gen_lowpart (QImode, out);
18580   emit_insn (gen_cmpintqi (outlow));
18581   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18583   if (operands[0] != out)
18584     emit_move_insn (operands[0], out);
18586   DONE;
18589 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18591 (define_expand "cmpintqi"
18592   [(set (match_dup 1)
18593         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18594    (set (match_dup 2)
18595         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18596    (parallel [(set (match_operand:QI 0 "register_operand" "")
18597                    (minus:QI (match_dup 1)
18598                              (match_dup 2)))
18599               (clobber (reg:CC FLAGS_REG))])]
18600   ""
18601   "operands[1] = gen_reg_rtx (QImode);
18602    operands[2] = gen_reg_rtx (QImode);")
18604 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18605 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18607 (define_expand "cmpstrnqi_nz_1"
18608   [(parallel [(set (reg:CC FLAGS_REG)
18609                    (compare:CC (match_operand 4 "memory_operand" "")
18610                                (match_operand 5 "memory_operand" "")))
18611               (use (match_operand 2 "register_operand" ""))
18612               (use (match_operand:SI 3 "immediate_operand" ""))
18613               (clobber (match_operand 0 "register_operand" ""))
18614               (clobber (match_operand 1 "register_operand" ""))
18615               (clobber (match_dup 2))])]
18616   ""
18617   "")
18619 (define_insn "*cmpstrnqi_nz_1"
18620   [(set (reg:CC FLAGS_REG)
18621         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18622                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18623    (use (match_operand:SI 6 "register_operand" "2"))
18624    (use (match_operand:SI 3 "immediate_operand" "i"))
18625    (clobber (match_operand:SI 0 "register_operand" "=S"))
18626    (clobber (match_operand:SI 1 "register_operand" "=D"))
18627    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18628   "!TARGET_64BIT"
18629   "repz{\;| }cmpsb"
18630   [(set_attr "type" "str")
18631    (set_attr "mode" "QI")
18632    (set_attr "prefix_rep" "1")])
18634 (define_insn "*cmpstrnqi_nz_rex_1"
18635   [(set (reg:CC FLAGS_REG)
18636         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18637                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18638    (use (match_operand:DI 6 "register_operand" "2"))
18639    (use (match_operand:SI 3 "immediate_operand" "i"))
18640    (clobber (match_operand:DI 0 "register_operand" "=S"))
18641    (clobber (match_operand:DI 1 "register_operand" "=D"))
18642    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18643   "TARGET_64BIT"
18644   "repz{\;| }cmpsb"
18645   [(set_attr "type" "str")
18646    (set_attr "mode" "QI")
18647    (set_attr "prefix_rep" "1")])
18649 ;; The same, but the count is not known to not be zero.
18651 (define_expand "cmpstrnqi_1"
18652   [(parallel [(set (reg:CC FLAGS_REG)
18653                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18654                                      (const_int 0))
18655                   (compare:CC (match_operand 4 "memory_operand" "")
18656                               (match_operand 5 "memory_operand" ""))
18657                   (const_int 0)))
18658               (use (match_operand:SI 3 "immediate_operand" ""))
18659               (use (reg:CC FLAGS_REG))
18660               (clobber (match_operand 0 "register_operand" ""))
18661               (clobber (match_operand 1 "register_operand" ""))
18662               (clobber (match_dup 2))])]
18663   ""
18664   "")
18666 (define_insn "*cmpstrnqi_1"
18667   [(set (reg:CC FLAGS_REG)
18668         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18669                              (const_int 0))
18670           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18671                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18672           (const_int 0)))
18673    (use (match_operand:SI 3 "immediate_operand" "i"))
18674    (use (reg:CC FLAGS_REG))
18675    (clobber (match_operand:SI 0 "register_operand" "=S"))
18676    (clobber (match_operand:SI 1 "register_operand" "=D"))
18677    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18678   "!TARGET_64BIT"
18679   "repz{\;| }cmpsb"
18680   [(set_attr "type" "str")
18681    (set_attr "mode" "QI")
18682    (set_attr "prefix_rep" "1")])
18684 (define_insn "*cmpstrnqi_rex_1"
18685   [(set (reg:CC FLAGS_REG)
18686         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18687                              (const_int 0))
18688           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18689                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18690           (const_int 0)))
18691    (use (match_operand:SI 3 "immediate_operand" "i"))
18692    (use (reg:CC FLAGS_REG))
18693    (clobber (match_operand:DI 0 "register_operand" "=S"))
18694    (clobber (match_operand:DI 1 "register_operand" "=D"))
18695    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18696   "TARGET_64BIT"
18697   "repz{\;| }cmpsb"
18698   [(set_attr "type" "str")
18699    (set_attr "mode" "QI")
18700    (set_attr "prefix_rep" "1")])
18702 (define_expand "strlensi"
18703   [(set (match_operand:SI 0 "register_operand" "")
18704         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18705                     (match_operand:QI 2 "immediate_operand" "")
18706                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18707   ""
18709  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18710    DONE;
18711  else
18712    FAIL;
18715 (define_expand "strlendi"
18716   [(set (match_operand:DI 0 "register_operand" "")
18717         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18718                     (match_operand:QI 2 "immediate_operand" "")
18719                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18720   ""
18722  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18723    DONE;
18724  else
18725    FAIL;
18728 (define_expand "strlenqi_1"
18729   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18730               (clobber (match_operand 1 "register_operand" ""))
18731               (clobber (reg:CC FLAGS_REG))])]
18732   ""
18733   "")
18735 (define_insn "*strlenqi_1"
18736   [(set (match_operand:SI 0 "register_operand" "=&c")
18737         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18738                     (match_operand:QI 2 "register_operand" "a")
18739                     (match_operand:SI 3 "immediate_operand" "i")
18740                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18741    (clobber (match_operand:SI 1 "register_operand" "=D"))
18742    (clobber (reg:CC FLAGS_REG))]
18743   "!TARGET_64BIT"
18744   "repnz{\;| }scasb"
18745   [(set_attr "type" "str")
18746    (set_attr "mode" "QI")
18747    (set_attr "prefix_rep" "1")])
18749 (define_insn "*strlenqi_rex_1"
18750   [(set (match_operand:DI 0 "register_operand" "=&c")
18751         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18752                     (match_operand:QI 2 "register_operand" "a")
18753                     (match_operand:DI 3 "immediate_operand" "i")
18754                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18755    (clobber (match_operand:DI 1 "register_operand" "=D"))
18756    (clobber (reg:CC FLAGS_REG))]
18757   "TARGET_64BIT"
18758   "repnz{\;| }scasb"
18759   [(set_attr "type" "str")
18760    (set_attr "mode" "QI")
18761    (set_attr "prefix_rep" "1")])
18763 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18764 ;; handled in combine, but it is not currently up to the task.
18765 ;; When used for their truth value, the cmpstrn* expanders generate
18766 ;; code like this:
18768 ;;   repz cmpsb
18769 ;;   seta       %al
18770 ;;   setb       %dl
18771 ;;   cmpb       %al, %dl
18772 ;;   jcc        label
18774 ;; The intermediate three instructions are unnecessary.
18776 ;; This one handles cmpstrn*_nz_1...
18777 (define_peephole2
18778   [(parallel[
18779      (set (reg:CC FLAGS_REG)
18780           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18781                       (mem:BLK (match_operand 5 "register_operand" ""))))
18782      (use (match_operand 6 "register_operand" ""))
18783      (use (match_operand:SI 3 "immediate_operand" ""))
18784      (clobber (match_operand 0 "register_operand" ""))
18785      (clobber (match_operand 1 "register_operand" ""))
18786      (clobber (match_operand 2 "register_operand" ""))])
18787    (set (match_operand:QI 7 "register_operand" "")
18788         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18789    (set (match_operand:QI 8 "register_operand" "")
18790         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18791    (set (reg FLAGS_REG)
18792         (compare (match_dup 7) (match_dup 8)))
18793   ]
18794   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18795   [(parallel[
18796      (set (reg:CC FLAGS_REG)
18797           (compare:CC (mem:BLK (match_dup 4))
18798                       (mem:BLK (match_dup 5))))
18799      (use (match_dup 6))
18800      (use (match_dup 3))
18801      (clobber (match_dup 0))
18802      (clobber (match_dup 1))
18803      (clobber (match_dup 2))])]
18804   "")
18806 ;; ...and this one handles cmpstrn*_1.
18807 (define_peephole2
18808   [(parallel[
18809      (set (reg:CC FLAGS_REG)
18810           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18811                                (const_int 0))
18812             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18813                         (mem:BLK (match_operand 5 "register_operand" "")))
18814             (const_int 0)))
18815      (use (match_operand:SI 3 "immediate_operand" ""))
18816      (use (reg:CC FLAGS_REG))
18817      (clobber (match_operand 0 "register_operand" ""))
18818      (clobber (match_operand 1 "register_operand" ""))
18819      (clobber (match_operand 2 "register_operand" ""))])
18820    (set (match_operand:QI 7 "register_operand" "")
18821         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18822    (set (match_operand:QI 8 "register_operand" "")
18823         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18824    (set (reg FLAGS_REG)
18825         (compare (match_dup 7) (match_dup 8)))
18826   ]
18827   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18828   [(parallel[
18829      (set (reg:CC FLAGS_REG)
18830           (if_then_else:CC (ne (match_dup 6)
18831                                (const_int 0))
18832             (compare:CC (mem:BLK (match_dup 4))
18833                         (mem:BLK (match_dup 5)))
18834             (const_int 0)))
18835      (use (match_dup 3))
18836      (use (reg:CC FLAGS_REG))
18837      (clobber (match_dup 0))
18838      (clobber (match_dup 1))
18839      (clobber (match_dup 2))])]
18840   "")
18844 ;; Conditional move instructions.
18846 (define_expand "movdicc"
18847   [(set (match_operand:DI 0 "register_operand" "")
18848         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18849                          (match_operand:DI 2 "general_operand" "")
18850                          (match_operand:DI 3 "general_operand" "")))]
18851   "TARGET_64BIT"
18852   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18854 (define_insn "x86_movdicc_0_m1_rex64"
18855   [(set (match_operand:DI 0 "register_operand" "=r")
18856         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18857           (const_int -1)
18858           (const_int 0)))
18859    (clobber (reg:CC FLAGS_REG))]
18860   "TARGET_64BIT"
18861   "sbb{q}\t%0, %0"
18862   ; Since we don't have the proper number of operands for an alu insn,
18863   ; fill in all the blanks.
18864   [(set_attr "type" "alu")
18865    (set_attr "pent_pair" "pu")
18866    (set_attr "memory" "none")
18867    (set_attr "imm_disp" "false")
18868    (set_attr "mode" "DI")
18869    (set_attr "length_immediate" "0")])
18871 (define_insn "*movdicc_c_rex64"
18872   [(set (match_operand:DI 0 "register_operand" "=r,r")
18873         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18874                                 [(reg FLAGS_REG) (const_int 0)])
18875                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18876                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18877   "TARGET_64BIT && TARGET_CMOVE
18878    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18879   "@
18880    cmov%O2%C1\t{%2, %0|%0, %2}
18881    cmov%O2%c1\t{%3, %0|%0, %3}"
18882   [(set_attr "type" "icmov")
18883    (set_attr "mode" "DI")])
18885 (define_expand "movsicc"
18886   [(set (match_operand:SI 0 "register_operand" "")
18887         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18888                          (match_operand:SI 2 "general_operand" "")
18889                          (match_operand:SI 3 "general_operand" "")))]
18890   ""
18891   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18893 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18894 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18895 ;; So just document what we're doing explicitly.
18897 (define_insn "x86_movsicc_0_m1"
18898   [(set (match_operand:SI 0 "register_operand" "=r")
18899         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18900           (const_int -1)
18901           (const_int 0)))
18902    (clobber (reg:CC FLAGS_REG))]
18903   ""
18904   "sbb{l}\t%0, %0"
18905   ; Since we don't have the proper number of operands for an alu insn,
18906   ; fill in all the blanks.
18907   [(set_attr "type" "alu")
18908    (set_attr "pent_pair" "pu")
18909    (set_attr "memory" "none")
18910    (set_attr "imm_disp" "false")
18911    (set_attr "mode" "SI")
18912    (set_attr "length_immediate" "0")])
18914 (define_insn "*movsicc_noc"
18915   [(set (match_operand:SI 0 "register_operand" "=r,r")
18916         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18917                                 [(reg FLAGS_REG) (const_int 0)])
18918                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18919                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18920   "TARGET_CMOVE
18921    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18922   "@
18923    cmov%O2%C1\t{%2, %0|%0, %2}
18924    cmov%O2%c1\t{%3, %0|%0, %3}"
18925   [(set_attr "type" "icmov")
18926    (set_attr "mode" "SI")])
18928 (define_expand "movhicc"
18929   [(set (match_operand:HI 0 "register_operand" "")
18930         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18931                          (match_operand:HI 2 "general_operand" "")
18932                          (match_operand:HI 3 "general_operand" "")))]
18933   "TARGET_HIMODE_MATH"
18934   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18936 (define_insn "*movhicc_noc"
18937   [(set (match_operand:HI 0 "register_operand" "=r,r")
18938         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18939                                 [(reg FLAGS_REG) (const_int 0)])
18940                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18941                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18942   "TARGET_CMOVE
18943    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18944   "@
18945    cmov%O2%C1\t{%2, %0|%0, %2}
18946    cmov%O2%c1\t{%3, %0|%0, %3}"
18947   [(set_attr "type" "icmov")
18948    (set_attr "mode" "HI")])
18950 (define_expand "movqicc"
18951   [(set (match_operand:QI 0 "register_operand" "")
18952         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18953                          (match_operand:QI 2 "general_operand" "")
18954                          (match_operand:QI 3 "general_operand" "")))]
18955   "TARGET_QIMODE_MATH"
18956   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18958 (define_insn_and_split "*movqicc_noc"
18959   [(set (match_operand:QI 0 "register_operand" "=r,r")
18960         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18961                                 [(match_operand 4 "flags_reg_operand" "")
18962                                  (const_int 0)])
18963                       (match_operand:QI 2 "register_operand" "r,0")
18964                       (match_operand:QI 3 "register_operand" "0,r")))]
18965   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18966   "#"
18967   "&& reload_completed"
18968   [(set (match_dup 0)
18969         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18970                       (match_dup 2)
18971                       (match_dup 3)))]
18972   "operands[0] = gen_lowpart (SImode, operands[0]);
18973    operands[2] = gen_lowpart (SImode, operands[2]);
18974    operands[3] = gen_lowpart (SImode, operands[3]);"
18975   [(set_attr "type" "icmov")
18976    (set_attr "mode" "SI")])
18978 (define_expand "movsfcc"
18979   [(set (match_operand:SF 0 "register_operand" "")
18980         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18981                          (match_operand:SF 2 "register_operand" "")
18982                          (match_operand:SF 3 "register_operand" "")))]
18983   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18984   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18986 (define_insn "*movsfcc_1_387"
18987   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18988         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18989                                 [(reg FLAGS_REG) (const_int 0)])
18990                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18991                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18992   "TARGET_80387 && TARGET_CMOVE
18993    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18994   "@
18995    fcmov%F1\t{%2, %0|%0, %2}
18996    fcmov%f1\t{%3, %0|%0, %3}
18997    cmov%O2%C1\t{%2, %0|%0, %2}
18998    cmov%O2%c1\t{%3, %0|%0, %3}"
18999   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19000    (set_attr "mode" "SF,SF,SI,SI")])
19002 (define_expand "movdfcc"
19003   [(set (match_operand:DF 0 "register_operand" "")
19004         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19005                          (match_operand:DF 2 "register_operand" "")
19006                          (match_operand:DF 3 "register_operand" "")))]
19007   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19008   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19010 (define_insn "*movdfcc_1"
19011   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19012         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19013                                 [(reg FLAGS_REG) (const_int 0)])
19014                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19015                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19016   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19017    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19018   "@
19019    fcmov%F1\t{%2, %0|%0, %2}
19020    fcmov%f1\t{%3, %0|%0, %3}
19021    #
19022    #"
19023   [(set_attr "type" "fcmov,fcmov,multi,multi")
19024    (set_attr "mode" "DF")])
19026 (define_insn "*movdfcc_1_rex64"
19027   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19028         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19029                                 [(reg FLAGS_REG) (const_int 0)])
19030                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19031                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19032   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19033    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19034   "@
19035    fcmov%F1\t{%2, %0|%0, %2}
19036    fcmov%f1\t{%3, %0|%0, %3}
19037    cmov%O2%C1\t{%2, %0|%0, %2}
19038    cmov%O2%c1\t{%3, %0|%0, %3}"
19039   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19040    (set_attr "mode" "DF")])
19042 (define_split
19043   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19044         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19045                                 [(match_operand 4 "flags_reg_operand" "")
19046                                  (const_int 0)])
19047                       (match_operand:DF 2 "nonimmediate_operand" "")
19048                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19049   "!TARGET_64BIT && reload_completed"
19050   [(set (match_dup 2)
19051         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19052                       (match_dup 5)
19053                       (match_dup 7)))
19054    (set (match_dup 3)
19055         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19056                       (match_dup 6)
19057                       (match_dup 8)))]
19058   "split_di (operands+2, 1, operands+5, operands+6);
19059    split_di (operands+3, 1, operands+7, operands+8);
19060    split_di (operands, 1, operands+2, operands+3);")
19062 (define_expand "movxfcc"
19063   [(set (match_operand:XF 0 "register_operand" "")
19064         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19065                          (match_operand:XF 2 "register_operand" "")
19066                          (match_operand:XF 3 "register_operand" "")))]
19067   "TARGET_80387 && TARGET_CMOVE"
19068   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19070 (define_insn "*movxfcc_1"
19071   [(set (match_operand:XF 0 "register_operand" "=f,f")
19072         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19073                                 [(reg FLAGS_REG) (const_int 0)])
19074                       (match_operand:XF 2 "register_operand" "f,0")
19075                       (match_operand:XF 3 "register_operand" "0,f")))]
19076   "TARGET_80387 && TARGET_CMOVE"
19077   "@
19078    fcmov%F1\t{%2, %0|%0, %2}
19079    fcmov%f1\t{%3, %0|%0, %3}"
19080   [(set_attr "type" "fcmov")
19081    (set_attr "mode" "XF")])
19083 ;; These versions of the min/max patterns are intentionally ignorant of
19084 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19085 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19086 ;; are undefined in this condition, we're certain this is correct.
19088 (define_insn "sminsf3"
19089   [(set (match_operand:SF 0 "register_operand" "=x")
19090         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19091                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19092   "TARGET_SSE_MATH"
19093   "minss\t{%2, %0|%0, %2}"
19094   [(set_attr "type" "sseadd")
19095    (set_attr "mode" "SF")])
19097 (define_insn "smaxsf3"
19098   [(set (match_operand:SF 0 "register_operand" "=x")
19099         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19100                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19101   "TARGET_SSE_MATH"
19102   "maxss\t{%2, %0|%0, %2}"
19103   [(set_attr "type" "sseadd")
19104    (set_attr "mode" "SF")])
19106 (define_insn "smindf3"
19107   [(set (match_operand:DF 0 "register_operand" "=x")
19108         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19109                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19110   "TARGET_SSE2 && TARGET_SSE_MATH"
19111   "minsd\t{%2, %0|%0, %2}"
19112   [(set_attr "type" "sseadd")
19113    (set_attr "mode" "DF")])
19115 (define_insn "smaxdf3"
19116   [(set (match_operand:DF 0 "register_operand" "=x")
19117         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19118                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19119   "TARGET_SSE2 && TARGET_SSE_MATH"
19120   "maxsd\t{%2, %0|%0, %2}"
19121   [(set_attr "type" "sseadd")
19122    (set_attr "mode" "DF")])
19124 ;; These versions of the min/max patterns implement exactly the operations
19125 ;;   min = (op1 < op2 ? op1 : op2)
19126 ;;   max = (!(op1 < op2) ? op1 : op2)
19127 ;; Their operands are not commutative, and thus they may be used in the
19128 ;; presence of -0.0 and NaN.
19130 (define_insn "*ieee_sminsf3"
19131   [(set (match_operand:SF 0 "register_operand" "=x")
19132         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19133                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19134                    UNSPEC_IEEE_MIN))]
19135   "TARGET_SSE_MATH"
19136   "minss\t{%2, %0|%0, %2}"
19137   [(set_attr "type" "sseadd")
19138    (set_attr "mode" "SF")])
19140 (define_insn "*ieee_smaxsf3"
19141   [(set (match_operand:SF 0 "register_operand" "=x")
19142         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19143                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19144                    UNSPEC_IEEE_MAX))]
19145   "TARGET_SSE_MATH"
19146   "maxss\t{%2, %0|%0, %2}"
19147   [(set_attr "type" "sseadd")
19148    (set_attr "mode" "SF")])
19150 (define_insn "*ieee_smindf3"
19151   [(set (match_operand:DF 0 "register_operand" "=x")
19152         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19153                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19154                    UNSPEC_IEEE_MIN))]
19155   "TARGET_SSE2 && TARGET_SSE_MATH"
19156   "minsd\t{%2, %0|%0, %2}"
19157   [(set_attr "type" "sseadd")
19158    (set_attr "mode" "DF")])
19160 (define_insn "*ieee_smaxdf3"
19161   [(set (match_operand:DF 0 "register_operand" "=x")
19162         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19163                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19164                    UNSPEC_IEEE_MAX))]
19165   "TARGET_SSE2 && TARGET_SSE_MATH"
19166   "maxsd\t{%2, %0|%0, %2}"
19167   [(set_attr "type" "sseadd")
19168    (set_attr "mode" "DF")])
19170 ;; Make two stack loads independent:
19171 ;;   fld aa              fld aa
19172 ;;   fld %st(0)     ->   fld bb
19173 ;;   fmul bb             fmul %st(1), %st
19175 ;; Actually we only match the last two instructions for simplicity.
19176 (define_peephole2
19177   [(set (match_operand 0 "fp_register_operand" "")
19178         (match_operand 1 "fp_register_operand" ""))
19179    (set (match_dup 0)
19180         (match_operator 2 "binary_fp_operator"
19181            [(match_dup 0)
19182             (match_operand 3 "memory_operand" "")]))]
19183   "REGNO (operands[0]) != REGNO (operands[1])"
19184   [(set (match_dup 0) (match_dup 3))
19185    (set (match_dup 0) (match_dup 4))]
19187   ;; The % modifier is not operational anymore in peephole2's, so we have to
19188   ;; swap the operands manually in the case of addition and multiplication.
19189   "if (COMMUTATIVE_ARITH_P (operands[2]))
19190      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19191                                  operands[0], operands[1]);
19192    else
19193      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19194                                  operands[1], operands[0]);")
19196 ;; Conditional addition patterns
19197 (define_expand "addqicc"
19198   [(match_operand:QI 0 "register_operand" "")
19199    (match_operand 1 "comparison_operator" "")
19200    (match_operand:QI 2 "register_operand" "")
19201    (match_operand:QI 3 "const_int_operand" "")]
19202   ""
19203   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19205 (define_expand "addhicc"
19206   [(match_operand:HI 0 "register_operand" "")
19207    (match_operand 1 "comparison_operator" "")
19208    (match_operand:HI 2 "register_operand" "")
19209    (match_operand:HI 3 "const_int_operand" "")]
19210   ""
19211   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19213 (define_expand "addsicc"
19214   [(match_operand:SI 0 "register_operand" "")
19215    (match_operand 1 "comparison_operator" "")
19216    (match_operand:SI 2 "register_operand" "")
19217    (match_operand:SI 3 "const_int_operand" "")]
19218   ""
19219   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19221 (define_expand "adddicc"
19222   [(match_operand:DI 0 "register_operand" "")
19223    (match_operand 1 "comparison_operator" "")
19224    (match_operand:DI 2 "register_operand" "")
19225    (match_operand:DI 3 "const_int_operand" "")]
19226   "TARGET_64BIT"
19227   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19230 ;; Misc patterns (?)
19232 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19233 ;; Otherwise there will be nothing to keep
19235 ;; [(set (reg ebp) (reg esp))]
19236 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19237 ;;  (clobber (eflags)]
19238 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19240 ;; in proper program order.
19241 (define_insn "pro_epilogue_adjust_stack_1"
19242   [(set (match_operand:SI 0 "register_operand" "=r,r")
19243         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19244                  (match_operand:SI 2 "immediate_operand" "i,i")))
19245    (clobber (reg:CC FLAGS_REG))
19246    (clobber (mem:BLK (scratch)))]
19247   "!TARGET_64BIT"
19249   switch (get_attr_type (insn))
19250     {
19251     case TYPE_IMOV:
19252       return "mov{l}\t{%1, %0|%0, %1}";
19254     case TYPE_ALU:
19255       if (CONST_INT_P (operands[2])
19256           && (INTVAL (operands[2]) == 128
19257               || (INTVAL (operands[2]) < 0
19258                   && INTVAL (operands[2]) != -128)))
19259         {
19260           operands[2] = GEN_INT (-INTVAL (operands[2]));
19261           return "sub{l}\t{%2, %0|%0, %2}";
19262         }
19263       return "add{l}\t{%2, %0|%0, %2}";
19265     case TYPE_LEA:
19266       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19267       return "lea{l}\t{%a2, %0|%0, %a2}";
19269     default:
19270       gcc_unreachable ();
19271     }
19273   [(set (attr "type")
19274         (cond [(eq_attr "alternative" "0")
19275                  (const_string "alu")
19276                (match_operand:SI 2 "const0_operand" "")
19277                  (const_string "imov")
19278               ]
19279               (const_string "lea")))
19280    (set_attr "mode" "SI")])
19282 (define_insn "pro_epilogue_adjust_stack_rex64"
19283   [(set (match_operand:DI 0 "register_operand" "=r,r")
19284         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19285                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19286    (clobber (reg:CC FLAGS_REG))
19287    (clobber (mem:BLK (scratch)))]
19288   "TARGET_64BIT"
19290   switch (get_attr_type (insn))
19291     {
19292     case TYPE_IMOV:
19293       return "mov{q}\t{%1, %0|%0, %1}";
19295     case TYPE_ALU:
19296       if (CONST_INT_P (operands[2])
19297           /* Avoid overflows.  */
19298           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19299           && (INTVAL (operands[2]) == 128
19300               || (INTVAL (operands[2]) < 0
19301                   && INTVAL (operands[2]) != -128)))
19302         {
19303           operands[2] = GEN_INT (-INTVAL (operands[2]));
19304           return "sub{q}\t{%2, %0|%0, %2}";
19305         }
19306       return "add{q}\t{%2, %0|%0, %2}";
19308     case TYPE_LEA:
19309       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19310       return "lea{q}\t{%a2, %0|%0, %a2}";
19312     default:
19313       gcc_unreachable ();
19314     }
19316   [(set (attr "type")
19317         (cond [(eq_attr "alternative" "0")
19318                  (const_string "alu")
19319                (match_operand:DI 2 "const0_operand" "")
19320                  (const_string "imov")
19321               ]
19322               (const_string "lea")))
19323    (set_attr "mode" "DI")])
19325 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19326   [(set (match_operand:DI 0 "register_operand" "=r,r")
19327         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19328                  (match_operand:DI 3 "immediate_operand" "i,i")))
19329    (use (match_operand:DI 2 "register_operand" "r,r"))
19330    (clobber (reg:CC FLAGS_REG))
19331    (clobber (mem:BLK (scratch)))]
19332   "TARGET_64BIT"
19334   switch (get_attr_type (insn))
19335     {
19336     case TYPE_ALU:
19337       return "add{q}\t{%2, %0|%0, %2}";
19339     case TYPE_LEA:
19340       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19341       return "lea{q}\t{%a2, %0|%0, %a2}";
19343     default:
19344       gcc_unreachable ();
19345     }
19347   [(set_attr "type" "alu,lea")
19348    (set_attr "mode" "DI")])
19350 (define_insn "allocate_stack_worker_32"
19351   [(set (match_operand:SI 0 "register_operand" "+a")
19352         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19353    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19354    (clobber (reg:CC FLAGS_REG))]
19355   "!TARGET_64BIT && TARGET_STACK_PROBE"
19356   "call\t__alloca"
19357   [(set_attr "type" "multi")
19358    (set_attr "length" "5")])
19360 (define_insn "allocate_stack_worker_64"
19361   [(set (match_operand:DI 0 "register_operand" "=a")
19362         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19363    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19364    (clobber (reg:DI R10_REG))
19365    (clobber (reg:DI R11_REG))
19366    (clobber (reg:CC FLAGS_REG))]
19367   "TARGET_64BIT && TARGET_STACK_PROBE"
19368   "call\t___chkstk"
19369   [(set_attr "type" "multi")
19370    (set_attr "length" "5")])
19372 (define_expand "allocate_stack"
19373   [(match_operand 0 "register_operand" "")
19374    (match_operand 1 "general_operand" "")]
19375   "TARGET_STACK_PROBE"
19377   rtx x;
19379 #ifndef CHECK_STACK_LIMIT
19380 #define CHECK_STACK_LIMIT 0
19381 #endif
19383   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19384       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19385     {
19386       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19387                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19388       if (x != stack_pointer_rtx)
19389         emit_move_insn (stack_pointer_rtx, x);
19390     }
19391   else
19392     {
19393       x = copy_to_mode_reg (Pmode, operands[1]);
19394       if (TARGET_64BIT)
19395         x = gen_allocate_stack_worker_64 (x);
19396       else
19397         x = gen_allocate_stack_worker_32 (x);
19398       emit_insn (x);
19399     }
19401   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19402   DONE;
19405 (define_expand "builtin_setjmp_receiver"
19406   [(label_ref (match_operand 0 "" ""))]
19407   "!TARGET_64BIT && flag_pic"
19409   if (TARGET_MACHO)
19410     {
19411       rtx xops[3];
19412       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19413       rtx label_rtx = gen_label_rtx ();
19414       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19415       xops[0] = xops[1] = picreg;
19416       xops[2] = gen_rtx_CONST (SImode,
19417                   gen_rtx_MINUS (SImode,
19418                     gen_rtx_LABEL_REF (SImode, label_rtx),
19419                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19420       ix86_expand_binary_operator (MINUS, SImode, xops);
19421     }
19422   else
19423     emit_insn (gen_set_got (pic_offset_table_rtx));
19424   DONE;
19427 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19429 (define_split
19430   [(set (match_operand 0 "register_operand" "")
19431         (match_operator 3 "promotable_binary_operator"
19432            [(match_operand 1 "register_operand" "")
19433             (match_operand 2 "aligned_operand" "")]))
19434    (clobber (reg:CC FLAGS_REG))]
19435   "! TARGET_PARTIAL_REG_STALL && reload_completed
19436    && ((GET_MODE (operands[0]) == HImode
19437         && ((!optimize_size && !TARGET_FAST_PREFIX)
19438             /* ??? next two lines just !satisfies_constraint_K (...) */
19439             || !CONST_INT_P (operands[2])
19440             || satisfies_constraint_K (operands[2])))
19441        || (GET_MODE (operands[0]) == QImode
19442            && (TARGET_PROMOTE_QImode || optimize_size)))"
19443   [(parallel [(set (match_dup 0)
19444                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19445               (clobber (reg:CC FLAGS_REG))])]
19446   "operands[0] = gen_lowpart (SImode, operands[0]);
19447    operands[1] = gen_lowpart (SImode, operands[1]);
19448    if (GET_CODE (operands[3]) != ASHIFT)
19449      operands[2] = gen_lowpart (SImode, operands[2]);
19450    PUT_MODE (operands[3], SImode);")
19452 ; Promote the QImode tests, as i386 has encoding of the AND
19453 ; instruction with 32-bit sign-extended immediate and thus the
19454 ; instruction size is unchanged, except in the %eax case for
19455 ; which it is increased by one byte, hence the ! optimize_size.
19456 (define_split
19457   [(set (match_operand 0 "flags_reg_operand" "")
19458         (match_operator 2 "compare_operator"
19459           [(and (match_operand 3 "aligned_operand" "")
19460                 (match_operand 4 "const_int_operand" ""))
19461            (const_int 0)]))
19462    (set (match_operand 1 "register_operand" "")
19463         (and (match_dup 3) (match_dup 4)))]
19464   "! TARGET_PARTIAL_REG_STALL && reload_completed
19465    /* Ensure that the operand will remain sign-extended immediate.  */
19466    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19467    && ! optimize_size
19468    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19469        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19470   [(parallel [(set (match_dup 0)
19471                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19472                                     (const_int 0)]))
19473               (set (match_dup 1)
19474                    (and:SI (match_dup 3) (match_dup 4)))])]
19476   operands[4]
19477     = gen_int_mode (INTVAL (operands[4])
19478                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19479   operands[1] = gen_lowpart (SImode, operands[1]);
19480   operands[3] = gen_lowpart (SImode, operands[3]);
19483 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19484 ; the TEST instruction with 32-bit sign-extended immediate and thus
19485 ; the instruction size would at least double, which is not what we
19486 ; want even with ! optimize_size.
19487 (define_split
19488   [(set (match_operand 0 "flags_reg_operand" "")
19489         (match_operator 1 "compare_operator"
19490           [(and (match_operand:HI 2 "aligned_operand" "")
19491                 (match_operand:HI 3 "const_int_operand" ""))
19492            (const_int 0)]))]
19493   "! TARGET_PARTIAL_REG_STALL && reload_completed
19494    /* Ensure that the operand will remain sign-extended immediate.  */
19495    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19496    && ! TARGET_FAST_PREFIX
19497    && ! optimize_size"
19498   [(set (match_dup 0)
19499         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19500                          (const_int 0)]))]
19502   operands[3]
19503     = gen_int_mode (INTVAL (operands[3])
19504                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19505   operands[2] = gen_lowpart (SImode, operands[2]);
19508 (define_split
19509   [(set (match_operand 0 "register_operand" "")
19510         (neg (match_operand 1 "register_operand" "")))
19511    (clobber (reg:CC FLAGS_REG))]
19512   "! TARGET_PARTIAL_REG_STALL && reload_completed
19513    && (GET_MODE (operands[0]) == HImode
19514        || (GET_MODE (operands[0]) == QImode
19515            && (TARGET_PROMOTE_QImode || optimize_size)))"
19516   [(parallel [(set (match_dup 0)
19517                    (neg:SI (match_dup 1)))
19518               (clobber (reg:CC FLAGS_REG))])]
19519   "operands[0] = gen_lowpart (SImode, operands[0]);
19520    operands[1] = gen_lowpart (SImode, operands[1]);")
19522 (define_split
19523   [(set (match_operand 0 "register_operand" "")
19524         (not (match_operand 1 "register_operand" "")))]
19525   "! TARGET_PARTIAL_REG_STALL && reload_completed
19526    && (GET_MODE (operands[0]) == HImode
19527        || (GET_MODE (operands[0]) == QImode
19528            && (TARGET_PROMOTE_QImode || optimize_size)))"
19529   [(set (match_dup 0)
19530         (not:SI (match_dup 1)))]
19531   "operands[0] = gen_lowpart (SImode, operands[0]);
19532    operands[1] = gen_lowpart (SImode, operands[1]);")
19534 (define_split
19535   [(set (match_operand 0 "register_operand" "")
19536         (if_then_else (match_operator 1 "comparison_operator"
19537                                 [(reg FLAGS_REG) (const_int 0)])
19538                       (match_operand 2 "register_operand" "")
19539                       (match_operand 3 "register_operand" "")))]
19540   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19541    && (GET_MODE (operands[0]) == HImode
19542        || (GET_MODE (operands[0]) == QImode
19543            && (TARGET_PROMOTE_QImode || optimize_size)))"
19544   [(set (match_dup 0)
19545         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19546   "operands[0] = gen_lowpart (SImode, operands[0]);
19547    operands[2] = gen_lowpart (SImode, operands[2]);
19548    operands[3] = gen_lowpart (SImode, operands[3]);")
19551 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19552 ;; transform a complex memory operation into two memory to register operations.
19554 ;; Don't push memory operands
19555 (define_peephole2
19556   [(set (match_operand:SI 0 "push_operand" "")
19557         (match_operand:SI 1 "memory_operand" ""))
19558    (match_scratch:SI 2 "r")]
19559   "!optimize_size && !TARGET_PUSH_MEMORY
19560    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19561   [(set (match_dup 2) (match_dup 1))
19562    (set (match_dup 0) (match_dup 2))]
19563   "")
19565 (define_peephole2
19566   [(set (match_operand:DI 0 "push_operand" "")
19567         (match_operand:DI 1 "memory_operand" ""))
19568    (match_scratch:DI 2 "r")]
19569   "!optimize_size && !TARGET_PUSH_MEMORY
19570    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19571   [(set (match_dup 2) (match_dup 1))
19572    (set (match_dup 0) (match_dup 2))]
19573   "")
19575 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19576 ;; SImode pushes.
19577 (define_peephole2
19578   [(set (match_operand:SF 0 "push_operand" "")
19579         (match_operand:SF 1 "memory_operand" ""))
19580    (match_scratch:SF 2 "r")]
19581   "!optimize_size && !TARGET_PUSH_MEMORY
19582    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19583   [(set (match_dup 2) (match_dup 1))
19584    (set (match_dup 0) (match_dup 2))]
19585   "")
19587 (define_peephole2
19588   [(set (match_operand:HI 0 "push_operand" "")
19589         (match_operand:HI 1 "memory_operand" ""))
19590    (match_scratch:HI 2 "r")]
19591   "!optimize_size && !TARGET_PUSH_MEMORY
19592    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19593   [(set (match_dup 2) (match_dup 1))
19594    (set (match_dup 0) (match_dup 2))]
19595   "")
19597 (define_peephole2
19598   [(set (match_operand:QI 0 "push_operand" "")
19599         (match_operand:QI 1 "memory_operand" ""))
19600    (match_scratch:QI 2 "q")]
19601   "!optimize_size && !TARGET_PUSH_MEMORY
19602    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19603   [(set (match_dup 2) (match_dup 1))
19604    (set (match_dup 0) (match_dup 2))]
19605   "")
19607 ;; Don't move an immediate directly to memory when the instruction
19608 ;; gets too big.
19609 (define_peephole2
19610   [(match_scratch:SI 1 "r")
19611    (set (match_operand:SI 0 "memory_operand" "")
19612         (const_int 0))]
19613   "! optimize_size
19614    && ! TARGET_USE_MOV0
19615    && TARGET_SPLIT_LONG_MOVES
19616    && get_attr_length (insn) >= ix86_cost->large_insn
19617    && peep2_regno_dead_p (0, FLAGS_REG)"
19618   [(parallel [(set (match_dup 1) (const_int 0))
19619               (clobber (reg:CC FLAGS_REG))])
19620    (set (match_dup 0) (match_dup 1))]
19621   "")
19623 (define_peephole2
19624   [(match_scratch:HI 1 "r")
19625    (set (match_operand:HI 0 "memory_operand" "")
19626         (const_int 0))]
19627   "! optimize_size
19628    && ! TARGET_USE_MOV0
19629    && TARGET_SPLIT_LONG_MOVES
19630    && get_attr_length (insn) >= ix86_cost->large_insn
19631    && peep2_regno_dead_p (0, FLAGS_REG)"
19632   [(parallel [(set (match_dup 2) (const_int 0))
19633               (clobber (reg:CC FLAGS_REG))])
19634    (set (match_dup 0) (match_dup 1))]
19635   "operands[2] = gen_lowpart (SImode, operands[1]);")
19637 (define_peephole2
19638   [(match_scratch:QI 1 "q")
19639    (set (match_operand:QI 0 "memory_operand" "")
19640         (const_int 0))]
19641   "! optimize_size
19642    && ! TARGET_USE_MOV0
19643    && TARGET_SPLIT_LONG_MOVES
19644    && get_attr_length (insn) >= ix86_cost->large_insn
19645    && peep2_regno_dead_p (0, FLAGS_REG)"
19646   [(parallel [(set (match_dup 2) (const_int 0))
19647               (clobber (reg:CC FLAGS_REG))])
19648    (set (match_dup 0) (match_dup 1))]
19649   "operands[2] = gen_lowpart (SImode, operands[1]);")
19651 (define_peephole2
19652   [(match_scratch:SI 2 "r")
19653    (set (match_operand:SI 0 "memory_operand" "")
19654         (match_operand:SI 1 "immediate_operand" ""))]
19655   "! optimize_size
19656    && get_attr_length (insn) >= ix86_cost->large_insn
19657    && TARGET_SPLIT_LONG_MOVES"
19658   [(set (match_dup 2) (match_dup 1))
19659    (set (match_dup 0) (match_dup 2))]
19660   "")
19662 (define_peephole2
19663   [(match_scratch:HI 2 "r")
19664    (set (match_operand:HI 0 "memory_operand" "")
19665         (match_operand:HI 1 "immediate_operand" ""))]
19666   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19667   && TARGET_SPLIT_LONG_MOVES"
19668   [(set (match_dup 2) (match_dup 1))
19669    (set (match_dup 0) (match_dup 2))]
19670   "")
19672 (define_peephole2
19673   [(match_scratch:QI 2 "q")
19674    (set (match_operand:QI 0 "memory_operand" "")
19675         (match_operand:QI 1 "immediate_operand" ""))]
19676   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19677   && TARGET_SPLIT_LONG_MOVES"
19678   [(set (match_dup 2) (match_dup 1))
19679    (set (match_dup 0) (match_dup 2))]
19680   "")
19682 ;; Don't compare memory with zero, load and use a test instead.
19683 (define_peephole2
19684   [(set (match_operand 0 "flags_reg_operand" "")
19685         (match_operator 1 "compare_operator"
19686           [(match_operand:SI 2 "memory_operand" "")
19687            (const_int 0)]))
19688    (match_scratch:SI 3 "r")]
19689   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19690   [(set (match_dup 3) (match_dup 2))
19691    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19692   "")
19694 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19695 ;; Don't split NOTs with a displacement operand, because resulting XOR
19696 ;; will not be pairable anyway.
19698 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19699 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19700 ;; so this split helps here as well.
19702 ;; Note: Can't do this as a regular split because we can't get proper
19703 ;; lifetime information then.
19705 (define_peephole2
19706   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19707         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19708   "!optimize_size
19709    && peep2_regno_dead_p (0, FLAGS_REG)
19710    && ((TARGET_NOT_UNPAIRABLE
19711         && (!MEM_P (operands[0])
19712             || !memory_displacement_operand (operands[0], SImode)))
19713        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))"
19714   [(parallel [(set (match_dup 0)
19715                    (xor:SI (match_dup 1) (const_int -1)))
19716               (clobber (reg:CC FLAGS_REG))])]
19717   "")
19719 (define_peephole2
19720   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19721         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19722   "!optimize_size
19723    && peep2_regno_dead_p (0, FLAGS_REG)
19724    && ((TARGET_NOT_UNPAIRABLE
19725         && (!MEM_P (operands[0])
19726             || !memory_displacement_operand (operands[0], HImode)))
19727        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))"
19728   [(parallel [(set (match_dup 0)
19729                    (xor:HI (match_dup 1) (const_int -1)))
19730               (clobber (reg:CC FLAGS_REG))])]
19731   "")
19733 (define_peephole2
19734   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19735         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19736   "!optimize_size
19737    && peep2_regno_dead_p (0, FLAGS_REG)
19738    && ((TARGET_NOT_UNPAIRABLE
19739         && (!MEM_P (operands[0])
19740             || !memory_displacement_operand (operands[0], QImode)))
19741        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))"
19742   [(parallel [(set (match_dup 0)
19743                    (xor:QI (match_dup 1) (const_int -1)))
19744               (clobber (reg:CC FLAGS_REG))])]
19745   "")
19747 ;; Non pairable "test imm, reg" instructions can be translated to
19748 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19749 ;; byte opcode instead of two, have a short form for byte operands),
19750 ;; so do it for other CPUs as well.  Given that the value was dead,
19751 ;; this should not create any new dependencies.  Pass on the sub-word
19752 ;; versions if we're concerned about partial register stalls.
19754 (define_peephole2
19755   [(set (match_operand 0 "flags_reg_operand" "")
19756         (match_operator 1 "compare_operator"
19757           [(and:SI (match_operand:SI 2 "register_operand" "")
19758                    (match_operand:SI 3 "immediate_operand" ""))
19759            (const_int 0)]))]
19760   "ix86_match_ccmode (insn, CCNOmode)
19761    && (true_regnum (operands[2]) != 0
19762        || satisfies_constraint_K (operands[3]))
19763    && peep2_reg_dead_p (1, operands[2])"
19764   [(parallel
19765      [(set (match_dup 0)
19766            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19767                             (const_int 0)]))
19768       (set (match_dup 2)
19769            (and:SI (match_dup 2) (match_dup 3)))])]
19770   "")
19772 ;; We don't need to handle HImode case, because it will be promoted to SImode
19773 ;; on ! TARGET_PARTIAL_REG_STALL
19775 (define_peephole2
19776   [(set (match_operand 0 "flags_reg_operand" "")
19777         (match_operator 1 "compare_operator"
19778           [(and:QI (match_operand:QI 2 "register_operand" "")
19779                    (match_operand:QI 3 "immediate_operand" ""))
19780            (const_int 0)]))]
19781   "! TARGET_PARTIAL_REG_STALL
19782    && ix86_match_ccmode (insn, CCNOmode)
19783    && true_regnum (operands[2]) != 0
19784    && peep2_reg_dead_p (1, operands[2])"
19785   [(parallel
19786      [(set (match_dup 0)
19787            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19788                             (const_int 0)]))
19789       (set (match_dup 2)
19790            (and:QI (match_dup 2) (match_dup 3)))])]
19791   "")
19793 (define_peephole2
19794   [(set (match_operand 0 "flags_reg_operand" "")
19795         (match_operator 1 "compare_operator"
19796           [(and:SI
19797              (zero_extract:SI
19798                (match_operand 2 "ext_register_operand" "")
19799                (const_int 8)
19800                (const_int 8))
19801              (match_operand 3 "const_int_operand" ""))
19802            (const_int 0)]))]
19803   "! TARGET_PARTIAL_REG_STALL
19804    && ix86_match_ccmode (insn, CCNOmode)
19805    && true_regnum (operands[2]) != 0
19806    && peep2_reg_dead_p (1, operands[2])"
19807   [(parallel [(set (match_dup 0)
19808                    (match_op_dup 1
19809                      [(and:SI
19810                         (zero_extract:SI
19811                           (match_dup 2)
19812                           (const_int 8)
19813                           (const_int 8))
19814                         (match_dup 3))
19815                       (const_int 0)]))
19816               (set (zero_extract:SI (match_dup 2)
19817                                     (const_int 8)
19818                                     (const_int 8))
19819                    (and:SI
19820                      (zero_extract:SI
19821                        (match_dup 2)
19822                        (const_int 8)
19823                        (const_int 8))
19824                      (match_dup 3)))])]
19825   "")
19827 ;; Don't do logical operations with memory inputs.
19828 (define_peephole2
19829   [(match_scratch:SI 2 "r")
19830    (parallel [(set (match_operand:SI 0 "register_operand" "")
19831                    (match_operator:SI 3 "arith_or_logical_operator"
19832                      [(match_dup 0)
19833                       (match_operand:SI 1 "memory_operand" "")]))
19834               (clobber (reg:CC FLAGS_REG))])]
19835   "! optimize_size && ! TARGET_READ_MODIFY"
19836   [(set (match_dup 2) (match_dup 1))
19837    (parallel [(set (match_dup 0)
19838                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19839               (clobber (reg:CC FLAGS_REG))])]
19840   "")
19842 (define_peephole2
19843   [(match_scratch:SI 2 "r")
19844    (parallel [(set (match_operand:SI 0 "register_operand" "")
19845                    (match_operator:SI 3 "arith_or_logical_operator"
19846                      [(match_operand:SI 1 "memory_operand" "")
19847                       (match_dup 0)]))
19848               (clobber (reg:CC FLAGS_REG))])]
19849   "! optimize_size && ! TARGET_READ_MODIFY"
19850   [(set (match_dup 2) (match_dup 1))
19851    (parallel [(set (match_dup 0)
19852                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19853               (clobber (reg:CC FLAGS_REG))])]
19854   "")
19856 ; Don't do logical operations with memory outputs
19858 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19859 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19860 ; the same decoder scheduling characteristics as the original.
19862 (define_peephole2
19863   [(match_scratch:SI 2 "r")
19864    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19865                    (match_operator:SI 3 "arith_or_logical_operator"
19866                      [(match_dup 0)
19867                       (match_operand:SI 1 "nonmemory_operand" "")]))
19868               (clobber (reg:CC FLAGS_REG))])]
19869   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19870   [(set (match_dup 2) (match_dup 0))
19871    (parallel [(set (match_dup 2)
19872                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19873               (clobber (reg:CC FLAGS_REG))])
19874    (set (match_dup 0) (match_dup 2))]
19875   "")
19877 (define_peephole2
19878   [(match_scratch:SI 2 "r")
19879    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19880                    (match_operator:SI 3 "arith_or_logical_operator"
19881                      [(match_operand:SI 1 "nonmemory_operand" "")
19882                       (match_dup 0)]))
19883               (clobber (reg:CC FLAGS_REG))])]
19884   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19885   [(set (match_dup 2) (match_dup 0))
19886    (parallel [(set (match_dup 2)
19887                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19888               (clobber (reg:CC FLAGS_REG))])
19889    (set (match_dup 0) (match_dup 2))]
19890   "")
19892 ;; Attempt to always use XOR for zeroing registers.
19893 (define_peephole2
19894   [(set (match_operand 0 "register_operand" "")
19895         (match_operand 1 "const0_operand" ""))]
19896   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19897    && (! TARGET_USE_MOV0 || optimize_size)
19898    && GENERAL_REG_P (operands[0])
19899    && peep2_regno_dead_p (0, FLAGS_REG)"
19900   [(parallel [(set (match_dup 0) (const_int 0))
19901               (clobber (reg:CC FLAGS_REG))])]
19903   operands[0] = gen_lowpart (word_mode, operands[0]);
19906 (define_peephole2
19907   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19908         (const_int 0))]
19909   "(GET_MODE (operands[0]) == QImode
19910     || GET_MODE (operands[0]) == HImode)
19911    && (! TARGET_USE_MOV0 || optimize_size)
19912    && peep2_regno_dead_p (0, FLAGS_REG)"
19913   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19914               (clobber (reg:CC FLAGS_REG))])])
19916 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19917 (define_peephole2
19918   [(set (match_operand 0 "register_operand" "")
19919         (const_int -1))]
19920   "(GET_MODE (operands[0]) == HImode
19921     || GET_MODE (operands[0]) == SImode
19922     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19923    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
19924    && peep2_regno_dead_p (0, FLAGS_REG)"
19925   [(parallel [(set (match_dup 0) (const_int -1))
19926               (clobber (reg:CC FLAGS_REG))])]
19927   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19928                               operands[0]);")
19930 ;; Attempt to convert simple leas to adds. These can be created by
19931 ;; move expanders.
19932 (define_peephole2
19933   [(set (match_operand:SI 0 "register_operand" "")
19934         (plus:SI (match_dup 0)
19935                  (match_operand:SI 1 "nonmemory_operand" "")))]
19936   "peep2_regno_dead_p (0, FLAGS_REG)"
19937   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19938               (clobber (reg:CC FLAGS_REG))])]
19939   "")
19941 (define_peephole2
19942   [(set (match_operand:SI 0 "register_operand" "")
19943         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19944                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19945   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19946   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19947               (clobber (reg:CC FLAGS_REG))])]
19948   "operands[2] = gen_lowpart (SImode, operands[2]);")
19950 (define_peephole2
19951   [(set (match_operand:DI 0 "register_operand" "")
19952         (plus:DI (match_dup 0)
19953                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19954   "peep2_regno_dead_p (0, FLAGS_REG)"
19955   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19956               (clobber (reg:CC FLAGS_REG))])]
19957   "")
19959 (define_peephole2
19960   [(set (match_operand:SI 0 "register_operand" "")
19961         (mult:SI (match_dup 0)
19962                  (match_operand:SI 1 "const_int_operand" "")))]
19963   "exact_log2 (INTVAL (operands[1])) >= 0
19964    && peep2_regno_dead_p (0, FLAGS_REG)"
19965   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19966               (clobber (reg:CC FLAGS_REG))])]
19967   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19969 (define_peephole2
19970   [(set (match_operand:DI 0 "register_operand" "")
19971         (mult:DI (match_dup 0)
19972                  (match_operand:DI 1 "const_int_operand" "")))]
19973   "exact_log2 (INTVAL (operands[1])) >= 0
19974    && peep2_regno_dead_p (0, FLAGS_REG)"
19975   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19976               (clobber (reg:CC FLAGS_REG))])]
19977   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19979 (define_peephole2
19980   [(set (match_operand:SI 0 "register_operand" "")
19981         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19982                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19983   "exact_log2 (INTVAL (operands[2])) >= 0
19984    && REGNO (operands[0]) == REGNO (operands[1])
19985    && peep2_regno_dead_p (0, FLAGS_REG)"
19986   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19987               (clobber (reg:CC FLAGS_REG))])]
19988   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19990 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19991 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19992 ;; many CPUs it is also faster, since special hardware to avoid esp
19993 ;; dependencies is present.
19995 ;; While some of these conversions may be done using splitters, we use peepholes
19996 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19998 ;; Convert prologue esp subtractions to push.
19999 ;; We need register to push.  In order to keep verify_flow_info happy we have
20000 ;; two choices
20001 ;; - use scratch and clobber it in order to avoid dependencies
20002 ;; - use already live register
20003 ;; We can't use the second way right now, since there is no reliable way how to
20004 ;; verify that given register is live.  First choice will also most likely in
20005 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20006 ;; call clobbered registers are dead.  We may want to use base pointer as an
20007 ;; alternative when no register is available later.
20009 (define_peephole2
20010   [(match_scratch:SI 0 "r")
20011    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20012               (clobber (reg:CC FLAGS_REG))
20013               (clobber (mem:BLK (scratch)))])]
20014   "optimize_size || !TARGET_SUB_ESP_4"
20015   [(clobber (match_dup 0))
20016    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20017               (clobber (mem:BLK (scratch)))])])
20019 (define_peephole2
20020   [(match_scratch:SI 0 "r")
20021    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20022               (clobber (reg:CC FLAGS_REG))
20023               (clobber (mem:BLK (scratch)))])]
20024   "optimize_size || !TARGET_SUB_ESP_8"
20025   [(clobber (match_dup 0))
20026    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20027    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20028               (clobber (mem:BLK (scratch)))])])
20030 ;; Convert esp subtractions to push.
20031 (define_peephole2
20032   [(match_scratch:SI 0 "r")
20033    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20034               (clobber (reg:CC FLAGS_REG))])]
20035   "optimize_size || !TARGET_SUB_ESP_4"
20036   [(clobber (match_dup 0))
20037    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20039 (define_peephole2
20040   [(match_scratch:SI 0 "r")
20041    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20042               (clobber (reg:CC FLAGS_REG))])]
20043   "optimize_size || !TARGET_SUB_ESP_8"
20044   [(clobber (match_dup 0))
20045    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20046    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20048 ;; Convert epilogue deallocator to pop.
20049 (define_peephole2
20050   [(match_scratch:SI 0 "r")
20051    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20052               (clobber (reg:CC FLAGS_REG))
20053               (clobber (mem:BLK (scratch)))])]
20054   "optimize_size || !TARGET_ADD_ESP_4"
20055   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20056               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20057               (clobber (mem:BLK (scratch)))])]
20058   "")
20060 ;; Two pops case is tricky, since pop causes dependency on destination register.
20061 ;; We use two registers if available.
20062 (define_peephole2
20063   [(match_scratch:SI 0 "r")
20064    (match_scratch:SI 1 "r")
20065    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20066               (clobber (reg:CC FLAGS_REG))
20067               (clobber (mem:BLK (scratch)))])]
20068   "optimize_size || !TARGET_ADD_ESP_8"
20069   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20070               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20071               (clobber (mem:BLK (scratch)))])
20072    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20073               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20074   "")
20076 (define_peephole2
20077   [(match_scratch:SI 0 "r")
20078    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20079               (clobber (reg:CC FLAGS_REG))
20080               (clobber (mem:BLK (scratch)))])]
20081   "optimize_size"
20082   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20083               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20084               (clobber (mem:BLK (scratch)))])
20085    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20086               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20087   "")
20089 ;; Convert esp additions to pop.
20090 (define_peephole2
20091   [(match_scratch:SI 0 "r")
20092    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20093               (clobber (reg:CC FLAGS_REG))])]
20094   ""
20095   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20096               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20097   "")
20099 ;; Two pops case is tricky, since pop causes dependency on destination register.
20100 ;; We use two registers if available.
20101 (define_peephole2
20102   [(match_scratch:SI 0 "r")
20103    (match_scratch:SI 1 "r")
20104    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20105               (clobber (reg:CC FLAGS_REG))])]
20106   ""
20107   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20108               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20109    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20110               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20111   "")
20113 (define_peephole2
20114   [(match_scratch:SI 0 "r")
20115    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20116               (clobber (reg:CC FLAGS_REG))])]
20117   "optimize_size"
20118   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20119               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20120    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20121               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20122   "")
20124 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20125 ;; required and register dies.  Similarly for 128 to plus -128.
20126 (define_peephole2
20127   [(set (match_operand 0 "flags_reg_operand" "")
20128         (match_operator 1 "compare_operator"
20129           [(match_operand 2 "register_operand" "")
20130            (match_operand 3 "const_int_operand" "")]))]
20131   "(INTVAL (operands[3]) == -1
20132     || INTVAL (operands[3]) == 1
20133     || INTVAL (operands[3]) == 128)
20134    && ix86_match_ccmode (insn, CCGCmode)
20135    && peep2_reg_dead_p (1, operands[2])"
20136   [(parallel [(set (match_dup 0)
20137                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20138               (clobber (match_dup 2))])]
20139   "")
20141 (define_peephole2
20142   [(match_scratch:DI 0 "r")
20143    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20144               (clobber (reg:CC FLAGS_REG))
20145               (clobber (mem:BLK (scratch)))])]
20146   "optimize_size || !TARGET_SUB_ESP_4"
20147   [(clobber (match_dup 0))
20148    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20149               (clobber (mem:BLK (scratch)))])])
20151 (define_peephole2
20152   [(match_scratch:DI 0 "r")
20153    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20154               (clobber (reg:CC FLAGS_REG))
20155               (clobber (mem:BLK (scratch)))])]
20156   "optimize_size || !TARGET_SUB_ESP_8"
20157   [(clobber (match_dup 0))
20158    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20159    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20160               (clobber (mem:BLK (scratch)))])])
20162 ;; Convert esp subtractions to push.
20163 (define_peephole2
20164   [(match_scratch:DI 0 "r")
20165    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20166               (clobber (reg:CC FLAGS_REG))])]
20167   "optimize_size || !TARGET_SUB_ESP_4"
20168   [(clobber (match_dup 0))
20169    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20171 (define_peephole2
20172   [(match_scratch:DI 0 "r")
20173    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20174               (clobber (reg:CC FLAGS_REG))])]
20175   "optimize_size || !TARGET_SUB_ESP_8"
20176   [(clobber (match_dup 0))
20177    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20178    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20180 ;; Convert epilogue deallocator to pop.
20181 (define_peephole2
20182   [(match_scratch:DI 0 "r")
20183    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20184               (clobber (reg:CC FLAGS_REG))
20185               (clobber (mem:BLK (scratch)))])]
20186   "optimize_size || !TARGET_ADD_ESP_4"
20187   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20188               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20189               (clobber (mem:BLK (scratch)))])]
20190   "")
20192 ;; Two pops case is tricky, since pop causes dependency on destination register.
20193 ;; We use two registers if available.
20194 (define_peephole2
20195   [(match_scratch:DI 0 "r")
20196    (match_scratch:DI 1 "r")
20197    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20198               (clobber (reg:CC FLAGS_REG))
20199               (clobber (mem:BLK (scratch)))])]
20200   "optimize_size || !TARGET_ADD_ESP_8"
20201   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20202               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20203               (clobber (mem:BLK (scratch)))])
20204    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20205               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20206   "")
20208 (define_peephole2
20209   [(match_scratch:DI 0 "r")
20210    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20211               (clobber (reg:CC FLAGS_REG))
20212               (clobber (mem:BLK (scratch)))])]
20213   "optimize_size"
20214   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20215               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20216               (clobber (mem:BLK (scratch)))])
20217    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20218               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20219   "")
20221 ;; Convert esp additions to pop.
20222 (define_peephole2
20223   [(match_scratch:DI 0 "r")
20224    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20225               (clobber (reg:CC FLAGS_REG))])]
20226   ""
20227   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20228               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20229   "")
20231 ;; Two pops case is tricky, since pop causes dependency on destination register.
20232 ;; We use two registers if available.
20233 (define_peephole2
20234   [(match_scratch:DI 0 "r")
20235    (match_scratch:DI 1 "r")
20236    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20237               (clobber (reg:CC FLAGS_REG))])]
20238   ""
20239   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20240               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20241    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20242               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20243   "")
20245 (define_peephole2
20246   [(match_scratch:DI 0 "r")
20247    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20248               (clobber (reg:CC FLAGS_REG))])]
20249   "optimize_size"
20250   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20251               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20252    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20253               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20254   "")
20256 ;; Convert imul by three, five and nine into lea
20257 (define_peephole2
20258   [(parallel
20259     [(set (match_operand:SI 0 "register_operand" "")
20260           (mult:SI (match_operand:SI 1 "register_operand" "")
20261                    (match_operand:SI 2 "const_int_operand" "")))
20262      (clobber (reg:CC FLAGS_REG))])]
20263   "INTVAL (operands[2]) == 3
20264    || INTVAL (operands[2]) == 5
20265    || INTVAL (operands[2]) == 9"
20266   [(set (match_dup 0)
20267         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20268                  (match_dup 1)))]
20269   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20271 (define_peephole2
20272   [(parallel
20273     [(set (match_operand:SI 0 "register_operand" "")
20274           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20275                    (match_operand:SI 2 "const_int_operand" "")))
20276      (clobber (reg:CC FLAGS_REG))])]
20277   "!optimize_size
20278    && (INTVAL (operands[2]) == 3
20279        || INTVAL (operands[2]) == 5
20280        || INTVAL (operands[2]) == 9)"
20281   [(set (match_dup 0) (match_dup 1))
20282    (set (match_dup 0)
20283         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20284                  (match_dup 0)))]
20285   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20287 (define_peephole2
20288   [(parallel
20289     [(set (match_operand:DI 0 "register_operand" "")
20290           (mult:DI (match_operand:DI 1 "register_operand" "")
20291                    (match_operand:DI 2 "const_int_operand" "")))
20292      (clobber (reg:CC FLAGS_REG))])]
20293   "TARGET_64BIT
20294    && (INTVAL (operands[2]) == 3
20295        || INTVAL (operands[2]) == 5
20296        || INTVAL (operands[2]) == 9)"
20297   [(set (match_dup 0)
20298         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20299                  (match_dup 1)))]
20300   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20302 (define_peephole2
20303   [(parallel
20304     [(set (match_operand:DI 0 "register_operand" "")
20305           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20306                    (match_operand:DI 2 "const_int_operand" "")))
20307      (clobber (reg:CC FLAGS_REG))])]
20308   "TARGET_64BIT
20309    && !optimize_size
20310    && (INTVAL (operands[2]) == 3
20311        || INTVAL (operands[2]) == 5
20312        || INTVAL (operands[2]) == 9)"
20313   [(set (match_dup 0) (match_dup 1))
20314    (set (match_dup 0)
20315         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20316                  (match_dup 0)))]
20317   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20319 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20320 ;; imul $32bit_imm, reg, reg is direct decoded.
20321 (define_peephole2
20322   [(match_scratch:DI 3 "r")
20323    (parallel [(set (match_operand:DI 0 "register_operand" "")
20324                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20325                             (match_operand:DI 2 "immediate_operand" "")))
20326               (clobber (reg:CC FLAGS_REG))])]
20327   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20328    && !satisfies_constraint_K (operands[2])"
20329   [(set (match_dup 3) (match_dup 1))
20330    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20331               (clobber (reg:CC FLAGS_REG))])]
20334 (define_peephole2
20335   [(match_scratch:SI 3 "r")
20336    (parallel [(set (match_operand:SI 0 "register_operand" "")
20337                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20338                             (match_operand:SI 2 "immediate_operand" "")))
20339               (clobber (reg:CC FLAGS_REG))])]
20340   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20341    && !satisfies_constraint_K (operands[2])"
20342   [(set (match_dup 3) (match_dup 1))
20343    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20344               (clobber (reg:CC FLAGS_REG))])]
20347 (define_peephole2
20348   [(match_scratch:SI 3 "r")
20349    (parallel [(set (match_operand:DI 0 "register_operand" "")
20350                    (zero_extend:DI
20351                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20352                               (match_operand:SI 2 "immediate_operand" ""))))
20353               (clobber (reg:CC FLAGS_REG))])]
20354   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20355    && !satisfies_constraint_K (operands[2])"
20356   [(set (match_dup 3) (match_dup 1))
20357    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20358               (clobber (reg:CC FLAGS_REG))])]
20361 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20362 ;; Convert it into imul reg, reg
20363 ;; It would be better to force assembler to encode instruction using long
20364 ;; immediate, but there is apparently no way to do so.
20365 (define_peephole2
20366   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20367                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20368                             (match_operand:DI 2 "const_int_operand" "")))
20369               (clobber (reg:CC FLAGS_REG))])
20370    (match_scratch:DI 3 "r")]
20371   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20372    && satisfies_constraint_K (operands[2])"
20373   [(set (match_dup 3) (match_dup 2))
20374    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20375               (clobber (reg:CC FLAGS_REG))])]
20377   if (!rtx_equal_p (operands[0], operands[1]))
20378     emit_move_insn (operands[0], operands[1]);
20381 (define_peephole2
20382   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20383                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20384                             (match_operand:SI 2 "const_int_operand" "")))
20385               (clobber (reg:CC FLAGS_REG))])
20386    (match_scratch:SI 3 "r")]
20387   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20388    && satisfies_constraint_K (operands[2])"
20389   [(set (match_dup 3) (match_dup 2))
20390    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20391               (clobber (reg:CC FLAGS_REG))])]
20393   if (!rtx_equal_p (operands[0], operands[1]))
20394     emit_move_insn (operands[0], operands[1]);
20397 (define_peephole2
20398   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20399                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20400                             (match_operand:HI 2 "immediate_operand" "")))
20401               (clobber (reg:CC FLAGS_REG))])
20402    (match_scratch:HI 3 "r")]
20403   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20404   [(set (match_dup 3) (match_dup 2))
20405    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20406               (clobber (reg:CC FLAGS_REG))])]
20408   if (!rtx_equal_p (operands[0], operands[1]))
20409     emit_move_insn (operands[0], operands[1]);
20412 ;; After splitting up read-modify operations, array accesses with memory
20413 ;; operands might end up in form:
20414 ;;  sall    $2, %eax
20415 ;;  movl    4(%esp), %edx
20416 ;;  addl    %edx, %eax
20417 ;; instead of pre-splitting:
20418 ;;  sall    $2, %eax
20419 ;;  addl    4(%esp), %eax
20420 ;; Turn it into:
20421 ;;  movl    4(%esp), %edx
20422 ;;  leal    (%edx,%eax,4), %eax
20424 (define_peephole2
20425   [(parallel [(set (match_operand 0 "register_operand" "")
20426                    (ashift (match_operand 1 "register_operand" "")
20427                            (match_operand 2 "const_int_operand" "")))
20428                (clobber (reg:CC FLAGS_REG))])
20429    (set (match_operand 3 "register_operand")
20430         (match_operand 4 "x86_64_general_operand" ""))
20431    (parallel [(set (match_operand 5 "register_operand" "")
20432                    (plus (match_operand 6 "register_operand" "")
20433                          (match_operand 7 "register_operand" "")))
20434                    (clobber (reg:CC FLAGS_REG))])]
20435   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20436    /* Validate MODE for lea.  */
20437    && ((!TARGET_PARTIAL_REG_STALL
20438         && (GET_MODE (operands[0]) == QImode
20439             || GET_MODE (operands[0]) == HImode))
20440        || GET_MODE (operands[0]) == SImode
20441        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20442    /* We reorder load and the shift.  */
20443    && !rtx_equal_p (operands[1], operands[3])
20444    && !reg_overlap_mentioned_p (operands[0], operands[4])
20445    /* Last PLUS must consist of operand 0 and 3.  */
20446    && !rtx_equal_p (operands[0], operands[3])
20447    && (rtx_equal_p (operands[3], operands[6])
20448        || rtx_equal_p (operands[3], operands[7]))
20449    && (rtx_equal_p (operands[0], operands[6])
20450        || rtx_equal_p (operands[0], operands[7]))
20451    /* The intermediate operand 0 must die or be same as output.  */
20452    && (rtx_equal_p (operands[0], operands[5])
20453        || peep2_reg_dead_p (3, operands[0]))"
20454   [(set (match_dup 3) (match_dup 4))
20455    (set (match_dup 0) (match_dup 1))]
20457   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20458   int scale = 1 << INTVAL (operands[2]);
20459   rtx index = gen_lowpart (Pmode, operands[1]);
20460   rtx base = gen_lowpart (Pmode, operands[3]);
20461   rtx dest = gen_lowpart (mode, operands[5]);
20463   operands[1] = gen_rtx_PLUS (Pmode, base,
20464                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20465   if (mode != Pmode)
20466     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20467   operands[0] = dest;
20470 ;; Call-value patterns last so that the wildcard operand does not
20471 ;; disrupt insn-recog's switch tables.
20473 (define_insn "*call_value_pop_0"
20474   [(set (match_operand 0 "" "")
20475         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20476               (match_operand:SI 2 "" "")))
20477    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20478                             (match_operand:SI 3 "immediate_operand" "")))]
20479   "!TARGET_64BIT"
20481   if (SIBLING_CALL_P (insn))
20482     return "jmp\t%P1";
20483   else
20484     return "call\t%P1";
20486   [(set_attr "type" "callv")])
20488 (define_insn "*call_value_pop_1"
20489   [(set (match_operand 0 "" "")
20490         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20491               (match_operand:SI 2 "" "")))
20492    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20493                             (match_operand:SI 3 "immediate_operand" "i")))]
20494   "!TARGET_64BIT"
20496   if (constant_call_address_operand (operands[1], Pmode))
20497     {
20498       if (SIBLING_CALL_P (insn))
20499         return "jmp\t%P1";
20500       else
20501         return "call\t%P1";
20502     }
20503   if (SIBLING_CALL_P (insn))
20504     return "jmp\t%A1";
20505   else
20506     return "call\t%A1";
20508   [(set_attr "type" "callv")])
20510 (define_insn "*call_value_0"
20511   [(set (match_operand 0 "" "")
20512         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20513               (match_operand:SI 2 "" "")))]
20514   "!TARGET_64BIT"
20516   if (SIBLING_CALL_P (insn))
20517     return "jmp\t%P1";
20518   else
20519     return "call\t%P1";
20521   [(set_attr "type" "callv")])
20523 (define_insn "*call_value_0_rex64"
20524   [(set (match_operand 0 "" "")
20525         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20526               (match_operand:DI 2 "const_int_operand" "")))]
20527   "TARGET_64BIT"
20529   if (SIBLING_CALL_P (insn))
20530     return "jmp\t%P1";
20531   else
20532     return "call\t%P1";
20534   [(set_attr "type" "callv")])
20536 (define_insn "*call_value_1"
20537   [(set (match_operand 0 "" "")
20538         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20539               (match_operand:SI 2 "" "")))]
20540   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20542   if (constant_call_address_operand (operands[1], Pmode))
20543     return "call\t%P1";
20544   return "call\t%A1";
20546   [(set_attr "type" "callv")])
20548 (define_insn "*sibcall_value_1"
20549   [(set (match_operand 0 "" "")
20550         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20551               (match_operand:SI 2 "" "")))]
20552   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20554   if (constant_call_address_operand (operands[1], Pmode))
20555     return "jmp\t%P1";
20556   return "jmp\t%A1";
20558   [(set_attr "type" "callv")])
20560 (define_insn "*call_value_1_rex64"
20561   [(set (match_operand 0 "" "")
20562         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20563               (match_operand:DI 2 "" "")))]
20564   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20565    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20567   if (constant_call_address_operand (operands[1], Pmode))
20568     return "call\t%P1";
20569   return "call\t%A1";
20571   [(set_attr "type" "callv")])
20573 (define_insn "*call_value_1_rex64_large"
20574   [(set (match_operand 0 "" "")
20575         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20576               (match_operand:DI 2 "" "")))]
20577   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20578   "call\t%A1"
20579   [(set_attr "type" "callv")])
20581 (define_insn "*sibcall_value_1_rex64"
20582   [(set (match_operand 0 "" "")
20583         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20584               (match_operand:DI 2 "" "")))]
20585   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20586   "jmp\t%P1"
20587   [(set_attr "type" "callv")])
20589 (define_insn "*sibcall_value_1_rex64_v"
20590   [(set (match_operand 0 "" "")
20591         (call (mem:QI (reg:DI R11_REG))
20592               (match_operand:DI 1 "" "")))]
20593   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20594   "jmp\t*%%r11"
20595   [(set_attr "type" "callv")])
20597 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20598 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20599 ;; caught for use by garbage collectors and the like.  Using an insn that
20600 ;; maps to SIGILL makes it more likely the program will rightfully die.
20601 ;; Keeping with tradition, "6" is in honor of #UD.
20602 (define_insn "trap"
20603   [(trap_if (const_int 1) (const_int 6))]
20604   ""
20605   { return ASM_SHORT "0x0b0f"; }
20606   [(set_attr "length" "2")])
20608 (define_expand "sse_prologue_save"
20609   [(parallel [(set (match_operand:BLK 0 "" "")
20610                    (unspec:BLK [(reg:DI 21)
20611                                 (reg:DI 22)
20612                                 (reg:DI 23)
20613                                 (reg:DI 24)
20614                                 (reg:DI 25)
20615                                 (reg:DI 26)
20616                                 (reg:DI 27)
20617                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20618               (use (match_operand:DI 1 "register_operand" ""))
20619               (use (match_operand:DI 2 "immediate_operand" ""))
20620               (use (label_ref:DI (match_operand 3 "" "")))])]
20621   "TARGET_64BIT"
20622   "")
20624 (define_insn "*sse_prologue_save_insn"
20625   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20626                           (match_operand:DI 4 "const_int_operand" "n")))
20627         (unspec:BLK [(reg:DI 21)
20628                      (reg:DI 22)
20629                      (reg:DI 23)
20630                      (reg:DI 24)
20631                      (reg:DI 25)
20632                      (reg:DI 26)
20633                      (reg:DI 27)
20634                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20635    (use (match_operand:DI 1 "register_operand" "r"))
20636    (use (match_operand:DI 2 "const_int_operand" "i"))
20637    (use (label_ref:DI (match_operand 3 "" "X")))]
20638   "TARGET_64BIT
20639    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20640    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20641   "*
20643   int i;
20644   operands[0] = gen_rtx_MEM (Pmode,
20645                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20646   output_asm_insn (\"jmp\\t%A1\", operands);
20647   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20648     {
20649       operands[4] = adjust_address (operands[0], DImode, i*16);
20650       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20651       PUT_MODE (operands[4], TImode);
20652       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20653         output_asm_insn (\"rex\", operands);
20654       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20655     }
20656   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20657                              CODE_LABEL_NUMBER (operands[3]));
20658   return \"\";
20660   "
20661   [(set_attr "type" "other")
20662    (set_attr "length_immediate" "0")
20663    (set_attr "length_address" "0")
20664    (set_attr "length" "135")
20665    (set_attr "memory" "store")
20666    (set_attr "modrm" "0")
20667    (set_attr "mode" "DI")])
20669 (define_expand "prefetch"
20670   [(prefetch (match_operand 0 "address_operand" "")
20671              (match_operand:SI 1 "const_int_operand" "")
20672              (match_operand:SI 2 "const_int_operand" ""))]
20673   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20675   int rw = INTVAL (operands[1]);
20676   int locality = INTVAL (operands[2]);
20678   gcc_assert (rw == 0 || rw == 1);
20679   gcc_assert (locality >= 0 && locality <= 3);
20680   gcc_assert (GET_MODE (operands[0]) == Pmode
20681               || GET_MODE (operands[0]) == VOIDmode);
20683   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20684      supported by SSE counterpart or the SSE prefetch is not available
20685      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20686      of locality.  */
20687   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20688     operands[2] = GEN_INT (3);
20689   else
20690     operands[1] = const0_rtx;
20693 (define_insn "*prefetch_sse"
20694   [(prefetch (match_operand:SI 0 "address_operand" "p")
20695              (const_int 0)
20696              (match_operand:SI 1 "const_int_operand" ""))]
20697   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20699   static const char * const patterns[4] = {
20700    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20701   };
20703   int locality = INTVAL (operands[1]);
20704   gcc_assert (locality >= 0 && locality <= 3);
20706   return patterns[locality];
20708   [(set_attr "type" "sse")
20709    (set_attr "memory" "none")])
20711 (define_insn "*prefetch_sse_rex"
20712   [(prefetch (match_operand:DI 0 "address_operand" "p")
20713              (const_int 0)
20714              (match_operand:SI 1 "const_int_operand" ""))]
20715   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20717   static const char * const patterns[4] = {
20718    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20719   };
20721   int locality = INTVAL (operands[1]);
20722   gcc_assert (locality >= 0 && locality <= 3);
20724   return patterns[locality];
20726   [(set_attr "type" "sse")
20727    (set_attr "memory" "none")])
20729 (define_insn "*prefetch_3dnow"
20730   [(prefetch (match_operand:SI 0 "address_operand" "p")
20731              (match_operand:SI 1 "const_int_operand" "n")
20732              (const_int 3))]
20733   "TARGET_3DNOW && !TARGET_64BIT"
20735   if (INTVAL (operands[1]) == 0)
20736     return "prefetch\t%a0";
20737   else
20738     return "prefetchw\t%a0";
20740   [(set_attr "type" "mmx")
20741    (set_attr "memory" "none")])
20743 (define_insn "*prefetch_3dnow_rex"
20744   [(prefetch (match_operand:DI 0 "address_operand" "p")
20745              (match_operand:SI 1 "const_int_operand" "n")
20746              (const_int 3))]
20747   "TARGET_3DNOW && TARGET_64BIT"
20749   if (INTVAL (operands[1]) == 0)
20750     return "prefetch\t%a0";
20751   else
20752     return "prefetchw\t%a0";
20754   [(set_attr "type" "mmx")
20755    (set_attr "memory" "none")])
20757 (define_expand "stack_protect_set"
20758   [(match_operand 0 "memory_operand" "")
20759    (match_operand 1 "memory_operand" "")]
20760   ""
20762 #ifdef TARGET_THREAD_SSP_OFFSET
20763   if (TARGET_64BIT)
20764     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20765                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20766   else
20767     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20768                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20769 #else
20770   if (TARGET_64BIT)
20771     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20772   else
20773     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20774 #endif
20775   DONE;
20778 (define_insn "stack_protect_set_si"
20779   [(set (match_operand:SI 0 "memory_operand" "=m")
20780         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20781    (set (match_scratch:SI 2 "=&r") (const_int 0))
20782    (clobber (reg:CC FLAGS_REG))]
20783   ""
20784   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20785   [(set_attr "type" "multi")])
20787 (define_insn "stack_protect_set_di"
20788   [(set (match_operand:DI 0 "memory_operand" "=m")
20789         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20790    (set (match_scratch:DI 2 "=&r") (const_int 0))
20791    (clobber (reg:CC FLAGS_REG))]
20792   "TARGET_64BIT"
20793   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20794   [(set_attr "type" "multi")])
20796 (define_insn "stack_tls_protect_set_si"
20797   [(set (match_operand:SI 0 "memory_operand" "=m")
20798         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20799    (set (match_scratch:SI 2 "=&r") (const_int 0))
20800    (clobber (reg:CC FLAGS_REG))]
20801   ""
20802   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20803   [(set_attr "type" "multi")])
20805 (define_insn "stack_tls_protect_set_di"
20806   [(set (match_operand:DI 0 "memory_operand" "=m")
20807         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20808    (set (match_scratch:DI 2 "=&r") (const_int 0))
20809    (clobber (reg:CC FLAGS_REG))]
20810   "TARGET_64BIT"
20811   {
20812      /* The kernel uses a different segment register for performance reasons; a
20813         system call would not have to trash the userspace segment register,
20814         which would be expensive */
20815      if (ix86_cmodel != CM_KERNEL)
20816         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20817      else
20818         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20819   }
20820   [(set_attr "type" "multi")])
20822 (define_expand "stack_protect_test"
20823   [(match_operand 0 "memory_operand" "")
20824    (match_operand 1 "memory_operand" "")
20825    (match_operand 2 "" "")]
20826   ""
20828   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20829   ix86_compare_op0 = operands[0];
20830   ix86_compare_op1 = operands[1];
20831   ix86_compare_emitted = flags;
20833 #ifdef TARGET_THREAD_SSP_OFFSET
20834   if (TARGET_64BIT)
20835     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20836                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20837   else
20838     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20839                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20840 #else
20841   if (TARGET_64BIT)
20842     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20843   else
20844     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20845 #endif
20846   emit_jump_insn (gen_beq (operands[2]));
20847   DONE;
20850 (define_insn "stack_protect_test_si"
20851   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20852         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20853                      (match_operand:SI 2 "memory_operand" "m")]
20854                     UNSPEC_SP_TEST))
20855    (clobber (match_scratch:SI 3 "=&r"))]
20856   ""
20857   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20858   [(set_attr "type" "multi")])
20860 (define_insn "stack_protect_test_di"
20861   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20862         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20863                      (match_operand:DI 2 "memory_operand" "m")]
20864                     UNSPEC_SP_TEST))
20865    (clobber (match_scratch:DI 3 "=&r"))]
20866   "TARGET_64BIT"
20867   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20868   [(set_attr "type" "multi")])
20870 (define_insn "stack_tls_protect_test_si"
20871   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20872         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20873                      (match_operand:SI 2 "const_int_operand" "i")]
20874                     UNSPEC_SP_TLS_TEST))
20875    (clobber (match_scratch:SI 3 "=r"))]
20876   ""
20877   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20878   [(set_attr "type" "multi")])
20880 (define_insn "stack_tls_protect_test_di"
20881   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20882         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20883                      (match_operand:DI 2 "const_int_operand" "i")]
20884                     UNSPEC_SP_TLS_TEST))
20885    (clobber (match_scratch:DI 3 "=r"))]
20886   "TARGET_64BIT"
20887   {
20888      /* The kernel uses a different segment register for performance reasons; a
20889         system call would not have to trash the userspace segment register,
20890         which would be expensive */
20891      if (ix86_cmodel != CM_KERNEL)
20892         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20893      else
20894         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20895   }
20896   [(set_attr "type" "multi")])
20898 (include "mmx.md")
20899 (include "sse.md")
20900 (include "sync.md")