* cfgcleanup.c, cfgexpand.c, cgraphunit.c, config/arm/arm.c,
[official-gcc.git] / gcc / config / i386 / i386.md
bloba298e1b4aa751192050de26e200f7faa84fec7f4
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
51 ;; UNSPEC usage:
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          30)
91    (UNSPEC_MASKMOV              31)
92    (UNSPEC_MOVMSK               32)
93    (UNSPEC_MOVNT                33)
94    (UNSPEC_MOVU                 34)
95    (UNSPEC_RCP                  35)
96    (UNSPEC_RSQRT                36)
97    (UNSPEC_SFENCE               37)
98    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
99    (UNSPEC_PFRCP                39)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDQQU                47)
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_TAN_ONE              82)
136    (UNSPEC_TAN_TAN              83)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
151   ])
153 (define_constants
154   [(UNSPECV_BLOCKAGE            0)
155    (UNSPECV_STACK_PROBE         1)
156    (UNSPECV_EMMS                2)
157    (UNSPECV_LDMXCSR             3)
158    (UNSPECV_STMXCSR             4)
159    (UNSPECV_FEMMS               5)
160    (UNSPECV_CLFLUSH             6)
161    (UNSPECV_ALIGN               7)
162    (UNSPECV_MONITOR             8)
163    (UNSPECV_MWAIT               9)
164    (UNSPECV_CMPXCHG_1           10)
165    (UNSPECV_CMPXCHG_2           11)
166    (UNSPECV_XCHG                12)
167    (UNSPECV_LOCK                13)
168   ])
170 ;; Registers by name.
171 (define_constants
172   [(BP_REG                       6)
173    (SP_REG                       7)
174    (FLAGS_REG                   17)
175    (FPSR_REG                    18)
176    (DIRFLAG_REG                 19)
177   ])
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; from i386.c.
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first.  This allows for better optimization.  For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
188 ;; Processor type.  This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
191   (const (symbol_ref "ix86_tune")))
193 ;; A basic instruction type.  Refinements due to arguments to be
194 ;; provided in other attributes.
195 (define_attr "type"
196   "other,multi,
197    alu,alu1,negnot,imov,imovx,lea,
198    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199    icmp,test,ibr,setcc,icmov,
200    push,pop,call,callv,leave,
201    str,cld,
202    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203    sselog,sselog1,sseiadd,sseishft,sseimul,
204    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206   (const_string "other"))
208 ;; Main data type used by the insn
209 (define_attr "mode"
210   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211   (const_string "unknown"))
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216            (const_string "i387")
217          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
219            (const_string "sse")
220          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
221            (const_string "mmx")
222          (eq_attr "type" "other")
223            (const_string "unknown")]
224          (const_string "integer")))
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
229            (const_int 0)
230          (eq_attr "unit" "i387,sse,mmx")
231            (const_int 0)
232          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
233                           imul,icmp,push,pop")
234            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235          (eq_attr "type" "imov,test")
236            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237          (eq_attr "type" "call")
238            (if_then_else (match_operand 0 "constant_call_address_operand" "")
239              (const_int 4)
240              (const_int 0))
241          (eq_attr "type" "callv")
242            (if_then_else (match_operand 1 "constant_call_address_operand" "")
243              (const_int 4)
244              (const_int 0))
245          ;; We don't know the size before shorten_branches.  Expect
246          ;; the instruction to fit for better scheduling.
247          (eq_attr "type" "ibr")
248            (const_int 1)
249          ]
250          (symbol_ref "/* Update immediate_length and other attributes! */
251                       gcc_unreachable (),1")))
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
256            (const_int 0)
257          (and (eq_attr "type" "call")
258               (match_operand 0 "constant_call_address_operand" ""))
259              (const_int 0)
260          (and (eq_attr "type" "callv")
261               (match_operand 1 "constant_call_address_operand" ""))
262              (const_int 0)
263          ]
264          (symbol_ref "ix86_attr_length_address_default (insn)")))
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268   (if_then_else (ior (eq_attr "mode" "HI")
269                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
270     (const_int 1)
271     (const_int 0)))
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" "" 
275   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
276     (const_int 1)
277     (const_int 0)))
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
281   (if_then_else 
282     (ior (eq_attr "type" "imovx,setcc,icmov")
283          (eq_attr "unit" "sse,mmx"))
284     (const_int 1)
285     (const_int 0)))
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289   (cond [(and (eq_attr "mode" "DI")
290               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
291            (const_int 1)
292          (and (eq_attr "mode" "QI")
293               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294                   (const_int 0)))
295            (const_int 1)
296          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
297              (const_int 0))
298            (const_int 1)
299         ]
300         (const_int 0)))
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304   (cond [(eq_attr "type" "str,cld,leave")
305            (const_int 0)
306          (eq_attr "unit" "i387")
307            (const_int 0)
308          (and (eq_attr "type" "incdec")
309               (ior (match_operand:SI 1 "register_operand" "")
310                    (match_operand:HI 1 "register_operand" "")))
311            (const_int 0)
312          (and (eq_attr "type" "push")
313               (not (match_operand 1 "memory_operand" "")))
314            (const_int 0)
315          (and (eq_attr "type" "pop")
316               (not (match_operand 0 "memory_operand" "")))
317            (const_int 0)
318          (and (eq_attr "type" "imov")
319               (ior (and (match_operand 0 "register_operand" "")
320                         (match_operand 1 "immediate_operand" ""))
321                    (ior (and (match_operand 0 "ax_reg_operand" "")
322                              (match_operand 1 "memory_displacement_only_operand" ""))
323                         (and (match_operand 0 "memory_displacement_only_operand" "")
324                              (match_operand 1 "ax_reg_operand" "")))))
325            (const_int 0)
326          (and (eq_attr "type" "call")
327               (match_operand 0 "constant_call_address_operand" ""))
328              (const_int 0)
329          (and (eq_attr "type" "callv")
330               (match_operand 1 "constant_call_address_operand" ""))
331              (const_int 0)
332          ]
333          (const_int 1)))
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
338 ;; other insns.
339 (define_attr "length" ""
340   (cond [(eq_attr "type" "other,multi,fistp,frndint")
341            (const_int 16)
342          (eq_attr "type" "fcmp")
343            (const_int 4)
344          (eq_attr "unit" "i387")
345            (plus (const_int 2)
346                  (plus (attr "prefix_data16")
347                        (attr "length_address")))]
348          (plus (plus (attr "modrm")
349                      (plus (attr "prefix_0f")
350                            (plus (attr "prefix_rex")
351                                  (const_int 1))))
352                (plus (attr "prefix_rep")
353                      (plus (attr "prefix_data16")
354                            (plus (attr "length_immediate")
355                                  (attr "length_address")))))))
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
361 (define_attr "memory" "none,load,store,both,unknown"
362   (cond [(eq_attr "type" "other,multi,str")
363            (const_string "unknown")
364          (eq_attr "type" "lea,fcmov,fpspc,cld")
365            (const_string "none")
366          (eq_attr "type" "fistp,leave")
367            (const_string "both")
368          (eq_attr "type" "frndint")
369            (const_string "load")
370          (eq_attr "type" "push")
371            (if_then_else (match_operand 1 "memory_operand" "")
372              (const_string "both")
373              (const_string "store"))
374          (eq_attr "type" "pop")
375            (if_then_else (match_operand 0 "memory_operand" "")
376              (const_string "both")
377              (const_string "load"))
378          (eq_attr "type" "setcc")
379            (if_then_else (match_operand 0 "memory_operand" "")
380              (const_string "store")
381              (const_string "none"))
382          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383            (if_then_else (ior (match_operand 0 "memory_operand" "")
384                               (match_operand 1 "memory_operand" ""))
385              (const_string "load")
386              (const_string "none"))
387          (eq_attr "type" "ibr")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "load")
390              (const_string "none"))
391          (eq_attr "type" "call")
392            (if_then_else (match_operand 0 "constant_call_address_operand" "")
393              (const_string "none")
394              (const_string "load"))
395          (eq_attr "type" "callv")
396            (if_then_else (match_operand 1 "constant_call_address_operand" "")
397              (const_string "none")
398              (const_string "load"))
399          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400               (match_operand 1 "memory_operand" ""))
401            (const_string "both")
402          (and (match_operand 0 "memory_operand" "")
403               (match_operand 1 "memory_operand" ""))
404            (const_string "both")
405          (match_operand 0 "memory_operand" "")
406            (const_string "store")
407          (match_operand 1 "memory_operand" "")
408            (const_string "load")
409          (and (eq_attr "type"
410                  "!alu1,negnot,ishift1,
411                    imov,imovx,icmp,test,
412                    fmov,fcmp,fsgn,
413                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414                    mmx,mmxmov,mmxcmp,mmxcvt")
415               (match_operand 2 "memory_operand" ""))
416            (const_string "load")
417          (and (eq_attr "type" "icmov")
418               (match_operand 3 "memory_operand" ""))
419            (const_string "load")
420         ]
421         (const_string "none")))
423 ;; Indicates if an instruction has both an immediate and a displacement.
425 (define_attr "imm_disp" "false,true,unknown"
426   (cond [(eq_attr "type" "other,multi")
427            (const_string "unknown")
428          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429               (and (match_operand 0 "memory_displacement_operand" "")
430                    (match_operand 1 "immediate_operand" "")))
431            (const_string "true")
432          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433               (and (match_operand 0 "memory_displacement_operand" "")
434                    (match_operand 2 "immediate_operand" "")))
435            (const_string "true")
436         ]
437         (const_string "false")))
439 ;; Indicates if an FP operation has an integer source.
441 (define_attr "fp_int_src" "false,true"
442   (const_string "false"))
444 ;; Defines rounding mode of an FP operation.
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447   (const_string "any"))
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451   [(set_attr "length" "128")
452    (set_attr "type" "multi")])
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
470 ;; Scheduling descriptions
472 (include "pentium.md")
473 (include "ppro.md")
474 (include "k6.md")
475 (include "athlon.md")
478 ;; Operand and operator predicates and constraints
480 (include "predicates.md")
481 (include "constraints.md")
484 ;; Compare instructions.
486 ;; All compare insns have expanders that save the operands away without
487 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
488 ;; after the cmp) will actually emit the cmpM.
490 (define_expand "cmpti"
491   [(set (reg:CC FLAGS_REG)
492         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
493                     (match_operand:TI 1 "x86_64_general_operand" "")))]
494   "TARGET_64BIT"
496   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
497     operands[0] = force_reg (TImode, operands[0]);
498   ix86_compare_op0 = operands[0];
499   ix86_compare_op1 = operands[1];
500   DONE;
503 (define_expand "cmpdi"
504   [(set (reg:CC FLAGS_REG)
505         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
506                     (match_operand:DI 1 "x86_64_general_operand" "")))]
507   ""
509   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
510     operands[0] = force_reg (DImode, operands[0]);
511   ix86_compare_op0 = operands[0];
512   ix86_compare_op1 = operands[1];
513   DONE;
516 (define_expand "cmpsi"
517   [(set (reg:CC FLAGS_REG)
518         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
519                     (match_operand:SI 1 "general_operand" "")))]
520   ""
522   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
523     operands[0] = force_reg (SImode, operands[0]);
524   ix86_compare_op0 = operands[0];
525   ix86_compare_op1 = operands[1];
526   DONE;
529 (define_expand "cmphi"
530   [(set (reg:CC FLAGS_REG)
531         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
532                     (match_operand:HI 1 "general_operand" "")))]
533   ""
535   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
536     operands[0] = force_reg (HImode, operands[0]);
537   ix86_compare_op0 = operands[0];
538   ix86_compare_op1 = operands[1];
539   DONE;
542 (define_expand "cmpqi"
543   [(set (reg:CC FLAGS_REG)
544         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
545                     (match_operand:QI 1 "general_operand" "")))]
546   "TARGET_QIMODE_MATH"
548   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
549     operands[0] = force_reg (QImode, operands[0]);
550   ix86_compare_op0 = operands[0];
551   ix86_compare_op1 = operands[1];
552   DONE;
555 (define_insn "cmpdi_ccno_1_rex64"
556   [(set (reg FLAGS_REG)
557         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
558                  (match_operand:DI 1 "const0_operand" "n,n")))]
559   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
560   "@
561    test{q}\t{%0, %0|%0, %0}
562    cmp{q}\t{%1, %0|%0, %1}"
563   [(set_attr "type" "test,icmp")
564    (set_attr "length_immediate" "0,1")
565    (set_attr "mode" "DI")])
567 (define_insn "*cmpdi_minus_1_rex64"
568   [(set (reg FLAGS_REG)
569         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
570                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
571                  (const_int 0)))]
572   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
573   "cmp{q}\t{%1, %0|%0, %1}"
574   [(set_attr "type" "icmp")
575    (set_attr "mode" "DI")])
577 (define_expand "cmpdi_1_rex64"
578   [(set (reg:CC FLAGS_REG)
579         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
580                     (match_operand:DI 1 "general_operand" "")))]
581   "TARGET_64BIT"
582   "")
584 (define_insn "cmpdi_1_insn_rex64"
585   [(set (reg FLAGS_REG)
586         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
587                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
588   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
589   "cmp{q}\t{%1, %0|%0, %1}"
590   [(set_attr "type" "icmp")
591    (set_attr "mode" "DI")])
594 (define_insn "*cmpsi_ccno_1"
595   [(set (reg FLAGS_REG)
596         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
597                  (match_operand:SI 1 "const0_operand" "n,n")))]
598   "ix86_match_ccmode (insn, CCNOmode)"
599   "@
600    test{l}\t{%0, %0|%0, %0}
601    cmp{l}\t{%1, %0|%0, %1}"
602   [(set_attr "type" "test,icmp")
603    (set_attr "length_immediate" "0,1")
604    (set_attr "mode" "SI")])
606 (define_insn "*cmpsi_minus_1"
607   [(set (reg FLAGS_REG)
608         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
609                            (match_operand:SI 1 "general_operand" "ri,mr"))
610                  (const_int 0)))]
611   "ix86_match_ccmode (insn, CCGOCmode)"
612   "cmp{l}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "SI")])
616 (define_expand "cmpsi_1"
617   [(set (reg:CC FLAGS_REG)
618         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619                     (match_operand:SI 1 "general_operand" "ri,mr")))]
620   ""
621   "")
623 (define_insn "*cmpsi_1_insn"
624   [(set (reg FLAGS_REG)
625         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
626                  (match_operand:SI 1 "general_operand" "ri,mr")))]
627   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628     && ix86_match_ccmode (insn, CCmode)"
629   "cmp{l}\t{%1, %0|%0, %1}"
630   [(set_attr "type" "icmp")
631    (set_attr "mode" "SI")])
633 (define_insn "*cmphi_ccno_1"
634   [(set (reg FLAGS_REG)
635         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
636                  (match_operand:HI 1 "const0_operand" "n,n")))]
637   "ix86_match_ccmode (insn, CCNOmode)"
638   "@
639    test{w}\t{%0, %0|%0, %0}
640    cmp{w}\t{%1, %0|%0, %1}"
641   [(set_attr "type" "test,icmp")
642    (set_attr "length_immediate" "0,1")
643    (set_attr "mode" "HI")])
645 (define_insn "*cmphi_minus_1"
646   [(set (reg FLAGS_REG)
647         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
648                            (match_operand:HI 1 "general_operand" "ri,mr"))
649                  (const_int 0)))]
650   "ix86_match_ccmode (insn, CCGOCmode)"
651   "cmp{w}\t{%1, %0|%0, %1}"
652   [(set_attr "type" "icmp")
653    (set_attr "mode" "HI")])
655 (define_insn "*cmphi_1"
656   [(set (reg FLAGS_REG)
657         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
658                  (match_operand:HI 1 "general_operand" "ri,mr")))]
659   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660    && ix86_match_ccmode (insn, CCmode)"
661   "cmp{w}\t{%1, %0|%0, %1}"
662   [(set_attr "type" "icmp")
663    (set_attr "mode" "HI")])
665 (define_insn "*cmpqi_ccno_1"
666   [(set (reg FLAGS_REG)
667         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
668                  (match_operand:QI 1 "const0_operand" "n,n")))]
669   "ix86_match_ccmode (insn, CCNOmode)"
670   "@
671    test{b}\t{%0, %0|%0, %0}
672    cmp{b}\t{$0, %0|%0, 0}"
673   [(set_attr "type" "test,icmp")
674    (set_attr "length_immediate" "0,1")
675    (set_attr "mode" "QI")])
677 (define_insn "*cmpqi_1"
678   [(set (reg FLAGS_REG)
679         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
680                  (match_operand:QI 1 "general_operand" "qi,mq")))]
681   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
682     && ix86_match_ccmode (insn, CCmode)"
683   "cmp{b}\t{%1, %0|%0, %1}"
684   [(set_attr "type" "icmp")
685    (set_attr "mode" "QI")])
687 (define_insn "*cmpqi_minus_1"
688   [(set (reg FLAGS_REG)
689         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
690                            (match_operand:QI 1 "general_operand" "qi,mq"))
691                  (const_int 0)))]
692   "ix86_match_ccmode (insn, CCGOCmode)"
693   "cmp{b}\t{%1, %0|%0, %1}"
694   [(set_attr "type" "icmp")
695    (set_attr "mode" "QI")])
697 (define_insn "*cmpqi_ext_1"
698   [(set (reg FLAGS_REG)
699         (compare
700           (match_operand:QI 0 "general_operand" "Qm")
701           (subreg:QI
702             (zero_extract:SI
703               (match_operand 1 "ext_register_operand" "Q")
704               (const_int 8)
705               (const_int 8)) 0)))]
706   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
707   "cmp{b}\t{%h1, %0|%0, %h1}"
708   [(set_attr "type" "icmp")
709    (set_attr "mode" "QI")])
711 (define_insn "*cmpqi_ext_1_rex64"
712   [(set (reg FLAGS_REG)
713         (compare
714           (match_operand:QI 0 "register_operand" "Q")
715           (subreg:QI
716             (zero_extract:SI
717               (match_operand 1 "ext_register_operand" "Q")
718               (const_int 8)
719               (const_int 8)) 0)))]
720   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721   "cmp{b}\t{%h1, %0|%0, %h1}"
722   [(set_attr "type" "icmp")
723    (set_attr "mode" "QI")])
725 (define_insn "*cmpqi_ext_2"
726   [(set (reg FLAGS_REG)
727         (compare
728           (subreg:QI
729             (zero_extract:SI
730               (match_operand 0 "ext_register_operand" "Q")
731               (const_int 8)
732               (const_int 8)) 0)
733           (match_operand:QI 1 "const0_operand" "n")))]
734   "ix86_match_ccmode (insn, CCNOmode)"
735   "test{b}\t%h0, %h0"
736   [(set_attr "type" "test")
737    (set_attr "length_immediate" "0")
738    (set_attr "mode" "QI")])
740 (define_expand "cmpqi_ext_3"
741   [(set (reg:CC FLAGS_REG)
742         (compare:CC
743           (subreg:QI
744             (zero_extract:SI
745               (match_operand 0 "ext_register_operand" "")
746               (const_int 8)
747               (const_int 8)) 0)
748           (match_operand:QI 1 "general_operand" "")))]
749   ""
750   "")
752 (define_insn "cmpqi_ext_3_insn"
753   [(set (reg FLAGS_REG)
754         (compare
755           (subreg:QI
756             (zero_extract:SI
757               (match_operand 0 "ext_register_operand" "Q")
758               (const_int 8)
759               (const_int 8)) 0)
760           (match_operand:QI 1 "general_operand" "Qmn")))]
761   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
762   "cmp{b}\t{%1, %h0|%h0, %1}"
763   [(set_attr "type" "icmp")
764    (set_attr "mode" "QI")])
766 (define_insn "cmpqi_ext_3_insn_rex64"
767   [(set (reg FLAGS_REG)
768         (compare
769           (subreg:QI
770             (zero_extract:SI
771               (match_operand 0 "ext_register_operand" "Q")
772               (const_int 8)
773               (const_int 8)) 0)
774           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
775   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776   "cmp{b}\t{%1, %h0|%h0, %1}"
777   [(set_attr "type" "icmp")
778    (set_attr "mode" "QI")])
780 (define_insn "*cmpqi_ext_4"
781   [(set (reg FLAGS_REG)
782         (compare
783           (subreg:QI
784             (zero_extract:SI
785               (match_operand 0 "ext_register_operand" "Q")
786               (const_int 8)
787               (const_int 8)) 0)
788           (subreg:QI
789             (zero_extract:SI
790               (match_operand 1 "ext_register_operand" "Q")
791               (const_int 8)
792               (const_int 8)) 0)))]
793   "ix86_match_ccmode (insn, CCmode)"
794   "cmp{b}\t{%h1, %h0|%h0, %h1}"
795   [(set_attr "type" "icmp")
796    (set_attr "mode" "QI")])
798 ;; These implement float point compares.
799 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
800 ;; which would allow mix and match FP modes on the compares.  Which is what
801 ;; the old patterns did, but with many more of them.
803 (define_expand "cmpxf"
804   [(set (reg:CC FLAGS_REG)
805         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
806                     (match_operand:XF 1 "nonmemory_operand" "")))]
807   "TARGET_80387"
809   ix86_compare_op0 = operands[0];
810   ix86_compare_op1 = operands[1];
811   DONE;
814 (define_expand "cmpdf"
815   [(set (reg:CC FLAGS_REG)
816         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
817                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
818   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
820   ix86_compare_op0 = operands[0];
821   ix86_compare_op1 = operands[1];
822   DONE;
825 (define_expand "cmpsf"
826   [(set (reg:CC FLAGS_REG)
827         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
828                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
829   "TARGET_80387 || TARGET_SSE_MATH"
831   ix86_compare_op0 = operands[0];
832   ix86_compare_op1 = operands[1];
833   DONE;
836 ;; FP compares, step 1:
837 ;; Set the FP condition codes.
839 ;; CCFPmode     compare with exceptions
840 ;; CCFPUmode    compare with no exceptions
842 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
843 ;; used to manage the reg stack popping would not be preserved.
845 (define_insn "*cmpfp_0"
846   [(set (match_operand:HI 0 "register_operand" "=a")
847         (unspec:HI
848           [(compare:CCFP
849              (match_operand 1 "register_operand" "f")
850              (match_operand 2 "const0_operand" "X"))]
851         UNSPEC_FNSTSW))]
852   "TARGET_80387
853    && FLOAT_MODE_P (GET_MODE (operands[1]))
854    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
855   "* return output_fp_compare (insn, operands, 0, 0);"
856   [(set_attr "type" "multi")
857    (set_attr "unit" "i387")
858    (set (attr "mode")
859      (cond [(match_operand:SF 1 "" "")
860               (const_string "SF")
861             (match_operand:DF 1 "" "")
862               (const_string "DF")
863            ]
864            (const_string "XF")))])
866 (define_insn "*cmpfp_sf"
867   [(set (match_operand:HI 0 "register_operand" "=a")
868         (unspec:HI
869           [(compare:CCFP
870              (match_operand:SF 1 "register_operand" "f")
871              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
872           UNSPEC_FNSTSW))]
873   "TARGET_80387"
874   "* return output_fp_compare (insn, operands, 0, 0);"
875   [(set_attr "type" "multi")
876    (set_attr "unit" "i387")
877    (set_attr "mode" "SF")])
879 (define_insn "*cmpfp_df"
880   [(set (match_operand:HI 0 "register_operand" "=a")
881         (unspec:HI
882           [(compare:CCFP
883              (match_operand:DF 1 "register_operand" "f")
884              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
885           UNSPEC_FNSTSW))]
886   "TARGET_80387"
887   "* return output_fp_compare (insn, operands, 0, 0);"
888   [(set_attr "type" "multi")
889    (set_attr "unit" "i387")
890    (set_attr "mode" "DF")])
892 (define_insn "*cmpfp_xf"
893   [(set (match_operand:HI 0 "register_operand" "=a")
894         (unspec:HI
895           [(compare:CCFP
896              (match_operand:XF 1 "register_operand" "f")
897              (match_operand:XF 2 "register_operand" "f"))]
898           UNSPEC_FNSTSW))]
899   "TARGET_80387"
900   "* return output_fp_compare (insn, operands, 0, 0);"
901   [(set_attr "type" "multi")
902    (set_attr "unit" "i387")
903    (set_attr "mode" "XF")])
905 (define_insn "*cmpfp_u"
906   [(set (match_operand:HI 0 "register_operand" "=a")
907         (unspec:HI
908           [(compare:CCFPU
909              (match_operand 1 "register_operand" "f")
910              (match_operand 2 "register_operand" "f"))]
911           UNSPEC_FNSTSW))]
912   "TARGET_80387
913    && FLOAT_MODE_P (GET_MODE (operands[1]))
914    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
915   "* return output_fp_compare (insn, operands, 0, 1);"
916   [(set_attr "type" "multi")
917    (set_attr "unit" "i387")
918    (set (attr "mode")
919      (cond [(match_operand:SF 1 "" "")
920               (const_string "SF")
921             (match_operand:DF 1 "" "")
922               (const_string "DF")
923            ]
924            (const_string "XF")))])
926 (define_insn "*cmpfp_<mode>"
927   [(set (match_operand:HI 0 "register_operand" "=a")
928         (unspec:HI
929           [(compare:CCFP
930              (match_operand 1 "register_operand" "f")
931              (match_operator 3 "float_operator"
932                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
933           UNSPEC_FNSTSW))]
934   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
935    && FLOAT_MODE_P (GET_MODE (operands[1]))
936    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
937   "* return output_fp_compare (insn, operands, 0, 0);"
938   [(set_attr "type" "multi")
939    (set_attr "unit" "i387")
940    (set_attr "fp_int_src" "true")
941    (set_attr "mode" "<MODE>")])
943 ;; FP compares, step 2
944 ;; Move the fpsw to ax.
946 (define_insn "x86_fnstsw_1"
947   [(set (match_operand:HI 0 "register_operand" "=a")
948         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
949   "TARGET_80387"
950   "fnstsw\t%0"
951   [(set_attr "length" "2")
952    (set_attr "mode" "SI")
953    (set_attr "unit" "i387")])
955 ;; FP compares, step 3
956 ;; Get ax into flags, general case.
958 (define_insn "x86_sahf_1"
959   [(set (reg:CC FLAGS_REG)
960         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
961   "!TARGET_64BIT"
962   "sahf"
963   [(set_attr "length" "1")
964    (set_attr "athlon_decode" "vector")
965    (set_attr "mode" "SI")])
967 ;; Pentium Pro can do steps 1 through 3 in one go.
969 (define_insn "*cmpfp_i_mixed"
970   [(set (reg:CCFP FLAGS_REG)
971         (compare:CCFP (match_operand 0 "register_operand" "f,x")
972                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
973   "TARGET_MIX_SSE_I387
974    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
975    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976   "* return output_fp_compare (insn, operands, 1, 0);"
977   [(set_attr "type" "fcmp,ssecomi")
978    (set (attr "mode")
979      (if_then_else (match_operand:SF 1 "" "")
980         (const_string "SF")
981         (const_string "DF")))
982    (set_attr "athlon_decode" "vector")])
984 (define_insn "*cmpfp_i_sse"
985   [(set (reg:CCFP FLAGS_REG)
986         (compare:CCFP (match_operand 0 "register_operand" "x")
987                       (match_operand 1 "nonimmediate_operand" "xm")))]
988   "TARGET_SSE_MATH
989    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991   "* return output_fp_compare (insn, operands, 1, 0);"
992   [(set_attr "type" "ssecomi")
993    (set (attr "mode")
994      (if_then_else (match_operand:SF 1 "" "")
995         (const_string "SF")
996         (const_string "DF")))
997    (set_attr "athlon_decode" "vector")])
999 (define_insn "*cmpfp_i_i387"
1000   [(set (reg:CCFP FLAGS_REG)
1001         (compare:CCFP (match_operand 0 "register_operand" "f")
1002                       (match_operand 1 "register_operand" "f")))]
1003   "TARGET_80387 && TARGET_CMOVE
1004    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1005    && FLOAT_MODE_P (GET_MODE (operands[0]))
1006    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007   "* return output_fp_compare (insn, operands, 1, 0);"
1008   [(set_attr "type" "fcmp")
1009    (set (attr "mode")
1010      (cond [(match_operand:SF 1 "" "")
1011               (const_string "SF")
1012             (match_operand:DF 1 "" "")
1013               (const_string "DF")
1014            ]
1015            (const_string "XF")))
1016    (set_attr "athlon_decode" "vector")])
1018 (define_insn "*cmpfp_iu_mixed"
1019   [(set (reg:CCFPU FLAGS_REG)
1020         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1021                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1022   "TARGET_MIX_SSE_I387
1023    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025   "* return output_fp_compare (insn, operands, 1, 1);"
1026   [(set_attr "type" "fcmp,ssecomi")
1027    (set (attr "mode")
1028      (if_then_else (match_operand:SF 1 "" "")
1029         (const_string "SF")
1030         (const_string "DF")))
1031    (set_attr "athlon_decode" "vector")])
1033 (define_insn "*cmpfp_iu_sse"
1034   [(set (reg:CCFPU FLAGS_REG)
1035         (compare:CCFPU (match_operand 0 "register_operand" "x")
1036                        (match_operand 1 "nonimmediate_operand" "xm")))]
1037   "TARGET_SSE_MATH
1038    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040   "* return output_fp_compare (insn, operands, 1, 1);"
1041   [(set_attr "type" "ssecomi")
1042    (set (attr "mode")
1043      (if_then_else (match_operand:SF 1 "" "")
1044         (const_string "SF")
1045         (const_string "DF")))
1046    (set_attr "athlon_decode" "vector")])
1048 (define_insn "*cmpfp_iu_387"
1049   [(set (reg:CCFPU FLAGS_REG)
1050         (compare:CCFPU (match_operand 0 "register_operand" "f")
1051                        (match_operand 1 "register_operand" "f")))]
1052   "TARGET_80387 && TARGET_CMOVE
1053    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1054    && FLOAT_MODE_P (GET_MODE (operands[0]))
1055    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056   "* return output_fp_compare (insn, operands, 1, 1);"
1057   [(set_attr "type" "fcmp")
1058    (set (attr "mode")
1059      (cond [(match_operand:SF 1 "" "")
1060               (const_string "SF")
1061             (match_operand:DF 1 "" "")
1062               (const_string "DF")
1063            ]
1064            (const_string "XF")))
1065    (set_attr "athlon_decode" "vector")])
1067 ;; Move instructions.
1069 ;; General case of fullword move.
1071 (define_expand "movsi"
1072   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1073         (match_operand:SI 1 "general_operand" ""))]
1074   ""
1075   "ix86_expand_move (SImode, operands); DONE;")
1077 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1078 ;; general_operand.
1080 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1081 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1082 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1083 ;; targets without our curiosities, and it is just as easy to represent
1084 ;; this differently.
1086 (define_insn "*pushsi2"
1087   [(set (match_operand:SI 0 "push_operand" "=<")
1088         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1089   "!TARGET_64BIT"
1090   "push{l}\t%1"
1091   [(set_attr "type" "push")
1092    (set_attr "mode" "SI")])
1094 ;; For 64BIT abi we always round up to 8 bytes.
1095 (define_insn "*pushsi2_rex64"
1096   [(set (match_operand:SI 0 "push_operand" "=X")
1097         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1098   "TARGET_64BIT"
1099   "push{q}\t%q1"
1100   [(set_attr "type" "push")
1101    (set_attr "mode" "SI")])
1103 (define_insn "*pushsi2_prologue"
1104   [(set (match_operand:SI 0 "push_operand" "=<")
1105         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1106    (clobber (mem:BLK (scratch)))]
1107   "!TARGET_64BIT"
1108   "push{l}\t%1"
1109   [(set_attr "type" "push")
1110    (set_attr "mode" "SI")])
1112 (define_insn "*popsi1_epilogue"
1113   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114         (mem:SI (reg:SI SP_REG)))
1115    (set (reg:SI SP_REG)
1116         (plus:SI (reg:SI SP_REG) (const_int 4)))
1117    (clobber (mem:BLK (scratch)))]
1118   "!TARGET_64BIT"
1119   "pop{l}\t%0"
1120   [(set_attr "type" "pop")
1121    (set_attr "mode" "SI")])
1123 (define_insn "popsi1"
1124   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1125         (mem:SI (reg:SI SP_REG)))
1126    (set (reg:SI SP_REG)
1127         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1128   "!TARGET_64BIT"
1129   "pop{l}\t%0"
1130   [(set_attr "type" "pop")
1131    (set_attr "mode" "SI")])
1133 (define_insn "*movsi_xor"
1134   [(set (match_operand:SI 0 "register_operand" "=r")
1135         (match_operand:SI 1 "const0_operand" "i"))
1136    (clobber (reg:CC FLAGS_REG))]
1137   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1138   "xor{l}\t{%0, %0|%0, %0}"
1139   [(set_attr "type" "alu1")
1140    (set_attr "mode" "SI")
1141    (set_attr "length_immediate" "0")])
1143 (define_insn "*movsi_or"
1144   [(set (match_operand:SI 0 "register_operand" "=r")
1145         (match_operand:SI 1 "immediate_operand" "i"))
1146    (clobber (reg:CC FLAGS_REG))]
1147   "reload_completed
1148    && operands[1] == constm1_rtx
1149    && (TARGET_PENTIUM || optimize_size)"
1151   operands[1] = constm1_rtx;
1152   return "or{l}\t{%1, %0|%0, %1}";
1154   [(set_attr "type" "alu1")
1155    (set_attr "mode" "SI")
1156    (set_attr "length_immediate" "1")])
1158 (define_insn "*movsi_1"
1159   [(set (match_operand:SI 0 "nonimmediate_operand"
1160                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1161         (match_operand:SI 1 "general_operand"
1162                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1163   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1165   switch (get_attr_type (insn))
1166     {
1167     case TYPE_SSELOG1:
1168       if (get_attr_mode (insn) == MODE_TI)
1169         return "pxor\t%0, %0";
1170       return "xorps\t%0, %0";
1172     case TYPE_SSEMOV:
1173       switch (get_attr_mode (insn))
1174         {
1175         case MODE_TI:
1176           return "movdqa\t{%1, %0|%0, %1}";
1177         case MODE_V4SF:
1178           return "movaps\t{%1, %0|%0, %1}";
1179         case MODE_SI:
1180           return "movd\t{%1, %0|%0, %1}";
1181         case MODE_SF:
1182           return "movss\t{%1, %0|%0, %1}";
1183         default:
1184           gcc_unreachable ();
1185         }
1187     case TYPE_MMXADD:
1188       return "pxor\t%0, %0";
1190     case TYPE_MMXMOV:
1191       if (get_attr_mode (insn) == MODE_DI)
1192         return "movq\t{%1, %0|%0, %1}";
1193       return "movd\t{%1, %0|%0, %1}";
1195     case TYPE_LEA:
1196       return "lea{l}\t{%1, %0|%0, %1}";
1198     default:
1199       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1200       return "mov{l}\t{%1, %0|%0, %1}";
1201     }
1203   [(set (attr "type")
1204      (cond [(eq_attr "alternative" "2")
1205               (const_string "mmxadd")
1206             (eq_attr "alternative" "3,4,5")
1207               (const_string "mmxmov")
1208             (eq_attr "alternative" "6")
1209               (const_string "sselog1")
1210             (eq_attr "alternative" "7,8,9,10,11")
1211               (const_string "ssemov")
1212             (match_operand:DI 1 "pic_32bit_operand" "")
1213               (const_string "lea")
1214            ]
1215            (const_string "imov")))
1216    (set (attr "mode")
1217      (cond [(eq_attr "alternative" "2,3")
1218               (const_string "DI")
1219             (eq_attr "alternative" "6,7")
1220               (if_then_else
1221                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1222                 (const_string "V4SF")
1223                 (const_string "TI"))
1224             (and (eq_attr "alternative" "8,9,10,11")
1225                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1226               (const_string "SF")
1227            ]
1228            (const_string "SI")))])
1230 ;; Stores and loads of ax to arbitrary constant address.
1231 ;; We fake an second form of instruction to force reload to load address
1232 ;; into register when rax is not available
1233 (define_insn "*movabssi_1_rex64"
1234   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1235         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1236   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1237   "@
1238    movabs{l}\t{%1, %P0|%P0, %1}
1239    mov{l}\t{%1, %a0|%a0, %1}"
1240   [(set_attr "type" "imov")
1241    (set_attr "modrm" "0,*")
1242    (set_attr "length_address" "8,0")
1243    (set_attr "length_immediate" "0,*")
1244    (set_attr "memory" "store")
1245    (set_attr "mode" "SI")])
1247 (define_insn "*movabssi_2_rex64"
1248   [(set (match_operand:SI 0 "register_operand" "=a,r")
1249         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1250   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1251   "@
1252    movabs{l}\t{%P1, %0|%0, %P1}
1253    mov{l}\t{%a1, %0|%0, %a1}"
1254   [(set_attr "type" "imov")
1255    (set_attr "modrm" "0,*")
1256    (set_attr "length_address" "8,0")
1257    (set_attr "length_immediate" "0")
1258    (set_attr "memory" "load")
1259    (set_attr "mode" "SI")])
1261 (define_insn "*swapsi"
1262   [(set (match_operand:SI 0 "register_operand" "+r")
1263         (match_operand:SI 1 "register_operand" "+r"))
1264    (set (match_dup 1)
1265         (match_dup 0))]
1266   ""
1267   "xchg{l}\t%1, %0"
1268   [(set_attr "type" "imov")
1269    (set_attr "mode" "SI")
1270    (set_attr "pent_pair" "np")
1271    (set_attr "athlon_decode" "vector")])
1273 (define_expand "movhi"
1274   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1275         (match_operand:HI 1 "general_operand" ""))]
1276   ""
1277   "ix86_expand_move (HImode, operands); DONE;")
1279 (define_insn "*pushhi2"
1280   [(set (match_operand:HI 0 "push_operand" "=X")
1281         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1282   "!TARGET_64BIT"
1283   "push{l}\t%k1"
1284   [(set_attr "type" "push")
1285    (set_attr "mode" "SI")])
1287 ;; For 64BIT abi we always round up to 8 bytes.
1288 (define_insn "*pushhi2_rex64"
1289   [(set (match_operand:HI 0 "push_operand" "=X")
1290         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1291   "TARGET_64BIT"
1292   "push{q}\t%q1"
1293   [(set_attr "type" "push")
1294    (set_attr "mode" "DI")])
1296 (define_insn "*movhi_1"
1297   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1298         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1299   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1301   switch (get_attr_type (insn))
1302     {
1303     case TYPE_IMOVX:
1304       /* movzwl is faster than movw on p2 due to partial word stalls,
1305          though not as fast as an aligned movl.  */
1306       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1307     default:
1308       if (get_attr_mode (insn) == MODE_SI)
1309         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1310       else
1311         return "mov{w}\t{%1, %0|%0, %1}";
1312     }
1314   [(set (attr "type")
1315      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1316               (const_string "imov")
1317             (and (eq_attr "alternative" "0")
1318                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319                           (const_int 0))
1320                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1321                           (const_int 0))))
1322               (const_string "imov")
1323             (and (eq_attr "alternative" "1,2")
1324                  (match_operand:HI 1 "aligned_operand" ""))
1325               (const_string "imov")
1326             (and (ne (symbol_ref "TARGET_MOVX")
1327                      (const_int 0))
1328                  (eq_attr "alternative" "0,2"))
1329               (const_string "imovx")
1330            ]
1331            (const_string "imov")))
1332     (set (attr "mode")
1333       (cond [(eq_attr "type" "imovx")
1334                (const_string "SI")
1335              (and (eq_attr "alternative" "1,2")
1336                   (match_operand:HI 1 "aligned_operand" ""))
1337                (const_string "SI")
1338              (and (eq_attr "alternative" "0")
1339                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340                            (const_int 0))
1341                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1342                            (const_int 0))))
1343                (const_string "SI")
1344             ]
1345             (const_string "HI")))])
1347 ;; Stores and loads of ax to arbitrary constant address.
1348 ;; We fake an second form of instruction to force reload to load address
1349 ;; into register when rax is not available
1350 (define_insn "*movabshi_1_rex64"
1351   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1352         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1353   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1354   "@
1355    movabs{w}\t{%1, %P0|%P0, %1}
1356    mov{w}\t{%1, %a0|%a0, %1}"
1357   [(set_attr "type" "imov")
1358    (set_attr "modrm" "0,*")
1359    (set_attr "length_address" "8,0")
1360    (set_attr "length_immediate" "0,*")
1361    (set_attr "memory" "store")
1362    (set_attr "mode" "HI")])
1364 (define_insn "*movabshi_2_rex64"
1365   [(set (match_operand:HI 0 "register_operand" "=a,r")
1366         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1367   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1368   "@
1369    movabs{w}\t{%P1, %0|%0, %P1}
1370    mov{w}\t{%a1, %0|%0, %a1}"
1371   [(set_attr "type" "imov")
1372    (set_attr "modrm" "0,*")
1373    (set_attr "length_address" "8,0")
1374    (set_attr "length_immediate" "0")
1375    (set_attr "memory" "load")
1376    (set_attr "mode" "HI")])
1378 (define_insn "*swaphi_1"
1379   [(set (match_operand:HI 0 "register_operand" "+r")
1380         (match_operand:HI 1 "register_operand" "+r"))
1381    (set (match_dup 1)
1382         (match_dup 0))]
1383   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1384   "xchg{l}\t%k1, %k0"
1385   [(set_attr "type" "imov")
1386    (set_attr "mode" "SI")
1387    (set_attr "pent_pair" "np")
1388    (set_attr "athlon_decode" "vector")])
1390 (define_insn "*swaphi_2"
1391   [(set (match_operand:HI 0 "register_operand" "+r")
1392         (match_operand:HI 1 "register_operand" "+r"))
1393    (set (match_dup 1)
1394         (match_dup 0))]
1395   "TARGET_PARTIAL_REG_STALL"
1396   "xchg{w}\t%1, %0"
1397   [(set_attr "type" "imov")
1398    (set_attr "mode" "HI")
1399    (set_attr "pent_pair" "np")
1400    (set_attr "athlon_decode" "vector")])
1402 (define_expand "movstricthi"
1403   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1404         (match_operand:HI 1 "general_operand" ""))]
1405   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1407   /* Don't generate memory->memory moves, go through a register */
1408   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1409     operands[1] = force_reg (HImode, operands[1]);
1412 (define_insn "*movstricthi_1"
1413   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1414         (match_operand:HI 1 "general_operand" "rn,m"))]
1415   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1416    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1417   "mov{w}\t{%1, %0|%0, %1}"
1418   [(set_attr "type" "imov")
1419    (set_attr "mode" "HI")])
1421 (define_insn "*movstricthi_xor"
1422   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1423         (match_operand:HI 1 "const0_operand" "i"))
1424    (clobber (reg:CC FLAGS_REG))]
1425   "reload_completed
1426    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1427   "xor{w}\t{%0, %0|%0, %0}"
1428   [(set_attr "type" "alu1")
1429    (set_attr "mode" "HI")
1430    (set_attr "length_immediate" "0")])
1432 (define_expand "movqi"
1433   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1434         (match_operand:QI 1 "general_operand" ""))]
1435   ""
1436   "ix86_expand_move (QImode, operands); DONE;")
1438 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1439 ;; "push a byte".  But actually we use pushl, which has the effect
1440 ;; of rounding the amount pushed up to a word.
1442 (define_insn "*pushqi2"
1443   [(set (match_operand:QI 0 "push_operand" "=X")
1444         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1445   "!TARGET_64BIT"
1446   "push{l}\t%k1"
1447   [(set_attr "type" "push")
1448    (set_attr "mode" "SI")])
1450 ;; For 64BIT abi we always round up to 8 bytes.
1451 (define_insn "*pushqi2_rex64"
1452   [(set (match_operand:QI 0 "push_operand" "=X")
1453         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1454   "TARGET_64BIT"
1455   "push{q}\t%q1"
1456   [(set_attr "type" "push")
1457    (set_attr "mode" "DI")])
1459 ;; Situation is quite tricky about when to choose full sized (SImode) move
1460 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1461 ;; partial register dependency machines (such as AMD Athlon), where QImode
1462 ;; moves issue extra dependency and for partial register stalls machines
1463 ;; that don't use QImode patterns (and QImode move cause stall on the next
1464 ;; instruction).
1466 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1467 ;; register stall machines with, where we use QImode instructions, since
1468 ;; partial register stall can be caused there.  Then we use movzx.
1469 (define_insn "*movqi_1"
1470   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1471         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1472   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474   switch (get_attr_type (insn))
1475     {
1476     case TYPE_IMOVX:
1477       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1478       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1479     default:
1480       if (get_attr_mode (insn) == MODE_SI)
1481         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1482       else
1483         return "mov{b}\t{%1, %0|%0, %1}";
1484     }
1486   [(set (attr "type")
1487      (cond [(and (eq_attr "alternative" "5")
1488                  (not (match_operand:QI 1 "aligned_operand" "")))
1489               (const_string "imovx")
1490             (ne (symbol_ref "optimize_size") (const_int 0))
1491               (const_string "imov")
1492             (and (eq_attr "alternative" "3")
1493                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1494                           (const_int 0))
1495                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1496                           (const_int 0))))
1497               (const_string "imov")
1498             (eq_attr "alternative" "3,5")
1499               (const_string "imovx")
1500             (and (ne (symbol_ref "TARGET_MOVX")
1501                      (const_int 0))
1502                  (eq_attr "alternative" "2"))
1503               (const_string "imovx")
1504            ]
1505            (const_string "imov")))
1506    (set (attr "mode")
1507       (cond [(eq_attr "alternative" "3,4,5")
1508                (const_string "SI")
1509              (eq_attr "alternative" "6")
1510                (const_string "QI")
1511              (eq_attr "type" "imovx")
1512                (const_string "SI")
1513              (and (eq_attr "type" "imov")
1514                   (and (eq_attr "alternative" "0,1")
1515                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1516                                 (const_int 0))
1517                             (and (eq (symbol_ref "optimize_size")
1518                                      (const_int 0))
1519                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1520                                      (const_int 0))))))
1521                (const_string "SI")
1522              ;; Avoid partial register stalls when not using QImode arithmetic
1523              (and (eq_attr "type" "imov")
1524                   (and (eq_attr "alternative" "0,1")
1525                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526                                 (const_int 0))
1527                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1528                                 (const_int 0)))))
1529                (const_string "SI")
1530            ]
1531            (const_string "QI")))])
1533 (define_expand "reload_outqi"
1534   [(parallel [(match_operand:QI 0 "" "=m")
1535               (match_operand:QI 1 "register_operand" "r")
1536               (match_operand:QI 2 "register_operand" "=&q")])]
1537   ""
1539   rtx op0, op1, op2;
1540   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1542   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1543   if (! q_regs_operand (op1, QImode))
1544     {
1545       emit_insn (gen_movqi (op2, op1));
1546       op1 = op2;
1547     }
1548   emit_insn (gen_movqi (op0, op1));
1549   DONE;
1552 (define_insn "*swapqi_1"
1553   [(set (match_operand:QI 0 "register_operand" "+r")
1554         (match_operand:QI 1 "register_operand" "+r"))
1555    (set (match_dup 1)
1556         (match_dup 0))]
1557   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1558   "xchg{l}\t%k1, %k0"
1559   [(set_attr "type" "imov")
1560    (set_attr "mode" "SI")
1561    (set_attr "pent_pair" "np")
1562    (set_attr "athlon_decode" "vector")])
1564 (define_insn "*swapqi_2"
1565   [(set (match_operand:QI 0 "register_operand" "+q")
1566         (match_operand:QI 1 "register_operand" "+q"))
1567    (set (match_dup 1)
1568         (match_dup 0))]
1569   "TARGET_PARTIAL_REG_STALL"
1570   "xchg{b}\t%1, %0"
1571   [(set_attr "type" "imov")
1572    (set_attr "mode" "QI")
1573    (set_attr "pent_pair" "np")
1574    (set_attr "athlon_decode" "vector")])
1576 (define_expand "movstrictqi"
1577   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1578         (match_operand:QI 1 "general_operand" ""))]
1579   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1581   /* Don't generate memory->memory moves, go through a register.  */
1582   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1583     operands[1] = force_reg (QImode, operands[1]);
1586 (define_insn "*movstrictqi_1"
1587   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1588         (match_operand:QI 1 "general_operand" "*qn,m"))]
1589   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1590    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1591   "mov{b}\t{%1, %0|%0, %1}"
1592   [(set_attr "type" "imov")
1593    (set_attr "mode" "QI")])
1595 (define_insn "*movstrictqi_xor"
1596   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1597         (match_operand:QI 1 "const0_operand" "i"))
1598    (clobber (reg:CC FLAGS_REG))]
1599   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1600   "xor{b}\t{%0, %0|%0, %0}"
1601   [(set_attr "type" "alu1")
1602    (set_attr "mode" "QI")
1603    (set_attr "length_immediate" "0")])
1605 (define_insn "*movsi_extv_1"
1606   [(set (match_operand:SI 0 "register_operand" "=R")
1607         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1608                          (const_int 8)
1609                          (const_int 8)))]
1610   ""
1611   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1612   [(set_attr "type" "imovx")
1613    (set_attr "mode" "SI")])
1615 (define_insn "*movhi_extv_1"
1616   [(set (match_operand:HI 0 "register_operand" "=R")
1617         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1618                          (const_int 8)
1619                          (const_int 8)))]
1620   ""
1621   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1622   [(set_attr "type" "imovx")
1623    (set_attr "mode" "SI")])
1625 (define_insn "*movqi_extv_1"
1626   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1627         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1628                          (const_int 8)
1629                          (const_int 8)))]
1630   "!TARGET_64BIT"
1632   switch (get_attr_type (insn))
1633     {
1634     case TYPE_IMOVX:
1635       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1636     default:
1637       return "mov{b}\t{%h1, %0|%0, %h1}";
1638     }
1640   [(set (attr "type")
1641      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1642                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1643                              (ne (symbol_ref "TARGET_MOVX")
1644                                  (const_int 0))))
1645         (const_string "imovx")
1646         (const_string "imov")))
1647    (set (attr "mode")
1648      (if_then_else (eq_attr "type" "imovx")
1649         (const_string "SI")
1650         (const_string "QI")))])
1652 (define_insn "*movqi_extv_1_rex64"
1653   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1654         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1655                          (const_int 8)
1656                          (const_int 8)))]
1657   "TARGET_64BIT"
1659   switch (get_attr_type (insn))
1660     {
1661     case TYPE_IMOVX:
1662       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1663     default:
1664       return "mov{b}\t{%h1, %0|%0, %h1}";
1665     }
1667   [(set (attr "type")
1668      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1669                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670                              (ne (symbol_ref "TARGET_MOVX")
1671                                  (const_int 0))))
1672         (const_string "imovx")
1673         (const_string "imov")))
1674    (set (attr "mode")
1675      (if_then_else (eq_attr "type" "imovx")
1676         (const_string "SI")
1677         (const_string "QI")))])
1679 ;; Stores and loads of ax to arbitrary constant address.
1680 ;; We fake an second form of instruction to force reload to load address
1681 ;; into register when rax is not available
1682 (define_insn "*movabsqi_1_rex64"
1683   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1684         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1685   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1686   "@
1687    movabs{b}\t{%1, %P0|%P0, %1}
1688    mov{b}\t{%1, %a0|%a0, %1}"
1689   [(set_attr "type" "imov")
1690    (set_attr "modrm" "0,*")
1691    (set_attr "length_address" "8,0")
1692    (set_attr "length_immediate" "0,*")
1693    (set_attr "memory" "store")
1694    (set_attr "mode" "QI")])
1696 (define_insn "*movabsqi_2_rex64"
1697   [(set (match_operand:QI 0 "register_operand" "=a,r")
1698         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1699   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1700   "@
1701    movabs{b}\t{%P1, %0|%0, %P1}
1702    mov{b}\t{%a1, %0|%0, %a1}"
1703   [(set_attr "type" "imov")
1704    (set_attr "modrm" "0,*")
1705    (set_attr "length_address" "8,0")
1706    (set_attr "length_immediate" "0")
1707    (set_attr "memory" "load")
1708    (set_attr "mode" "QI")])
1710 (define_insn "*movdi_extzv_1"
1711   [(set (match_operand:DI 0 "register_operand" "=R")
1712         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1713                          (const_int 8)
1714                          (const_int 8)))]
1715   "TARGET_64BIT"
1716   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1717   [(set_attr "type" "imovx")
1718    (set_attr "mode" "DI")])
1720 (define_insn "*movsi_extzv_1"
1721   [(set (match_operand:SI 0 "register_operand" "=R")
1722         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1723                          (const_int 8)
1724                          (const_int 8)))]
1725   ""
1726   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727   [(set_attr "type" "imovx")
1728    (set_attr "mode" "SI")])
1730 (define_insn "*movqi_extzv_2"
1731   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733                                     (const_int 8)
1734                                     (const_int 8)) 0))]
1735   "!TARGET_64BIT"
1737   switch (get_attr_type (insn))
1738     {
1739     case TYPE_IMOVX:
1740       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741     default:
1742       return "mov{b}\t{%h1, %0|%0, %h1}";
1743     }
1745   [(set (attr "type")
1746      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748                              (ne (symbol_ref "TARGET_MOVX")
1749                                  (const_int 0))))
1750         (const_string "imovx")
1751         (const_string "imov")))
1752    (set (attr "mode")
1753      (if_then_else (eq_attr "type" "imovx")
1754         (const_string "SI")
1755         (const_string "QI")))])
1757 (define_insn "*movqi_extzv_2_rex64"
1758   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1760                                     (const_int 8)
1761                                     (const_int 8)) 0))]
1762   "TARGET_64BIT"
1764   switch (get_attr_type (insn))
1765     {
1766     case TYPE_IMOVX:
1767       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1768     default:
1769       return "mov{b}\t{%h1, %0|%0, %h1}";
1770     }
1772   [(set (attr "type")
1773      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774                         (ne (symbol_ref "TARGET_MOVX")
1775                             (const_int 0)))
1776         (const_string "imovx")
1777         (const_string "imov")))
1778    (set (attr "mode")
1779      (if_then_else (eq_attr "type" "imovx")
1780         (const_string "SI")
1781         (const_string "QI")))])
1783 (define_insn "movsi_insv_1"
1784   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1785                          (const_int 8)
1786                          (const_int 8))
1787         (match_operand:SI 1 "general_operand" "Qmn"))]
1788   "!TARGET_64BIT"
1789   "mov{b}\t{%b1, %h0|%h0, %b1}"
1790   [(set_attr "type" "imov")
1791    (set_attr "mode" "QI")])
1793 (define_insn "movdi_insv_1_rex64"
1794   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1795                          (const_int 8)
1796                          (const_int 8))
1797         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1798   "TARGET_64BIT"
1799   "mov{b}\t{%b1, %h0|%h0, %b1}"
1800   [(set_attr "type" "imov")
1801    (set_attr "mode" "QI")])
1803 (define_insn "*movqi_insv_2"
1804   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1805                          (const_int 8)
1806                          (const_int 8))
1807         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1808                      (const_int 8)))]
1809   ""
1810   "mov{b}\t{%h1, %h0|%h0, %h1}"
1811   [(set_attr "type" "imov")
1812    (set_attr "mode" "QI")])
1814 (define_expand "movdi"
1815   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1816         (match_operand:DI 1 "general_operand" ""))]
1817   ""
1818   "ix86_expand_move (DImode, operands); DONE;")
1820 (define_insn "*pushdi"
1821   [(set (match_operand:DI 0 "push_operand" "=<")
1822         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1823   "!TARGET_64BIT"
1824   "#")
1826 (define_insn "*pushdi2_rex64"
1827   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1828         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1829   "TARGET_64BIT"
1830   "@
1831    push{q}\t%1
1832    #"
1833   [(set_attr "type" "push,multi")
1834    (set_attr "mode" "DI")])
1836 ;; Convert impossible pushes of immediate to existing instructions.
1837 ;; First try to get scratch register and go through it.  In case this
1838 ;; fails, push sign extended lower part first and then overwrite
1839 ;; upper part by 32bit move.
1840 (define_peephole2
1841   [(match_scratch:DI 2 "r")
1842    (set (match_operand:DI 0 "push_operand" "")
1843         (match_operand:DI 1 "immediate_operand" ""))]
1844   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1845    && !x86_64_immediate_operand (operands[1], DImode)"
1846   [(set (match_dup 2) (match_dup 1))
1847    (set (match_dup 0) (match_dup 2))]
1848   "")
1850 ;; We need to define this as both peepholer and splitter for case
1851 ;; peephole2 pass is not run.
1852 ;; "&& 1" is needed to keep it from matching the previous pattern.
1853 (define_peephole2
1854   [(set (match_operand:DI 0 "push_operand" "")
1855         (match_operand:DI 1 "immediate_operand" ""))]
1856   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858   [(set (match_dup 0) (match_dup 1))
1859    (set (match_dup 2) (match_dup 3))]
1860   "split_di (operands + 1, 1, operands + 2, operands + 3);
1861    operands[1] = gen_lowpart (DImode, operands[2]);
1862    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1863                                                     GEN_INT (4)));
1864   ")
1866 (define_split
1867   [(set (match_operand:DI 0 "push_operand" "")
1868         (match_operand:DI 1 "immediate_operand" ""))]
1869   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1870                     ? flow2_completed : reload_completed)
1871    && !symbolic_operand (operands[1], DImode)
1872    && !x86_64_immediate_operand (operands[1], DImode)"
1873   [(set (match_dup 0) (match_dup 1))
1874    (set (match_dup 2) (match_dup 3))]
1875   "split_di (operands + 1, 1, operands + 2, operands + 3);
1876    operands[1] = gen_lowpart (DImode, operands[2]);
1877    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1878                                                     GEN_INT (4)));
1879   ")
1881 (define_insn "*pushdi2_prologue_rex64"
1882   [(set (match_operand:DI 0 "push_operand" "=<")
1883         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1884    (clobber (mem:BLK (scratch)))]
1885   "TARGET_64BIT"
1886   "push{q}\t%1"
1887   [(set_attr "type" "push")
1888    (set_attr "mode" "DI")])
1890 (define_insn "*popdi1_epilogue_rex64"
1891   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892         (mem:DI (reg:DI SP_REG)))
1893    (set (reg:DI SP_REG)
1894         (plus:DI (reg:DI SP_REG) (const_int 8)))
1895    (clobber (mem:BLK (scratch)))]
1896   "TARGET_64BIT"
1897   "pop{q}\t%0"
1898   [(set_attr "type" "pop")
1899    (set_attr "mode" "DI")])
1901 (define_insn "popdi1"
1902   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903         (mem:DI (reg:DI SP_REG)))
1904    (set (reg:DI SP_REG)
1905         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1906   "TARGET_64BIT"
1907   "pop{q}\t%0"
1908   [(set_attr "type" "pop")
1909    (set_attr "mode" "DI")])
1911 (define_insn "*movdi_xor_rex64"
1912   [(set (match_operand:DI 0 "register_operand" "=r")
1913         (match_operand:DI 1 "const0_operand" "i"))
1914    (clobber (reg:CC FLAGS_REG))]
1915   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1916    && reload_completed"
1917   "xor{l}\t{%k0, %k0|%k0, %k0}"
1918   [(set_attr "type" "alu1")
1919    (set_attr "mode" "SI")
1920    (set_attr "length_immediate" "0")])
1922 (define_insn "*movdi_or_rex64"
1923   [(set (match_operand:DI 0 "register_operand" "=r")
1924         (match_operand:DI 1 "const_int_operand" "i"))
1925    (clobber (reg:CC FLAGS_REG))]
1926   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1927    && reload_completed
1928    && operands[1] == constm1_rtx"
1930   operands[1] = constm1_rtx;
1931   return "or{q}\t{%1, %0|%0, %1}";
1933   [(set_attr "type" "alu1")
1934    (set_attr "mode" "DI")
1935    (set_attr "length_immediate" "1")])
1937 (define_insn "*movdi_2"
1938   [(set (match_operand:DI 0 "nonimmediate_operand"
1939                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1940         (match_operand:DI 1 "general_operand"
1941                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1942   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943   "@
1944    #
1945    #
1946    pxor\t%0, %0
1947    movq\t{%1, %0|%0, %1}
1948    movq\t{%1, %0|%0, %1}
1949    pxor\t%0, %0
1950    movq\t{%1, %0|%0, %1}
1951    movdqa\t{%1, %0|%0, %1}
1952    movq\t{%1, %0|%0, %1}
1953    xorps\t%0, %0
1954    movlps\t{%1, %0|%0, %1}
1955    movaps\t{%1, %0|%0, %1}
1956    movlps\t{%1, %0|%0, %1}"
1957   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1958    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1960 (define_split
1961   [(set (match_operand:DI 0 "push_operand" "")
1962         (match_operand:DI 1 "general_operand" ""))]
1963   "!TARGET_64BIT && reload_completed
1964    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1965   [(const_int 0)]
1966   "ix86_split_long_move (operands); DONE;")
1968 ;; %%% This multiword shite has got to go.
1969 (define_split
1970   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1971         (match_operand:DI 1 "general_operand" ""))]
1972   "!TARGET_64BIT && reload_completed
1973    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1974    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1975   [(const_int 0)]
1976   "ix86_split_long_move (operands); DONE;")
1978 (define_insn "*movdi_1_rex64"
1979   [(set (match_operand:DI 0 "nonimmediate_operand"
1980                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1981         (match_operand:DI 1 "general_operand"
1982                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1983   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1985   switch (get_attr_type (insn))
1986     {
1987     case TYPE_SSECVT:
1988       if (which_alternative == 13)
1989         return "movq2dq\t{%1, %0|%0, %1}";
1990       else
1991         return "movdq2q\t{%1, %0|%0, %1}";
1992     case TYPE_SSEMOV:
1993       if (get_attr_mode (insn) == MODE_TI)
1994           return "movdqa\t{%1, %0|%0, %1}";
1995       /* FALLTHRU */
1996     case TYPE_MMXMOV:
1997       /* Moves from and into integer register is done using movd opcode with
1998          REX prefix.  */
1999       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000           return "movd\t{%1, %0|%0, %1}";
2001       return "movq\t{%1, %0|%0, %1}";
2002     case TYPE_SSELOG1:
2003     case TYPE_MMXADD:
2004       return "pxor\t%0, %0";
2005     case TYPE_MULTI:
2006       return "#";
2007     case TYPE_LEA:
2008       return "lea{q}\t{%a1, %0|%0, %a1}";
2009     default:
2010       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2011       if (get_attr_mode (insn) == MODE_SI)
2012         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013       else if (which_alternative == 2)
2014         return "movabs{q}\t{%1, %0|%0, %1}";
2015       else
2016         return "mov{q}\t{%1, %0|%0, %1}";
2017     }
2019   [(set (attr "type")
2020      (cond [(eq_attr "alternative" "5")
2021               (const_string "mmxadd")
2022             (eq_attr "alternative" "6,7,8")
2023               (const_string "mmxmov")
2024             (eq_attr "alternative" "9")
2025               (const_string "sselog1")
2026             (eq_attr "alternative" "10,11,12")
2027               (const_string "ssemov")
2028             (eq_attr "alternative" "13,14")
2029               (const_string "ssecvt")
2030             (eq_attr "alternative" "4")
2031               (const_string "multi")
2032             (match_operand:DI 1 "pic_32bit_operand" "")
2033               (const_string "lea")
2034            ]
2035            (const_string "imov")))
2036    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2037    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2038    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2040 ;; Stores and loads of ax to arbitrary constant address.
2041 ;; We fake an second form of instruction to force reload to load address
2042 ;; into register when rax is not available
2043 (define_insn "*movabsdi_1_rex64"
2044   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2045         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2046   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2047   "@
2048    movabs{q}\t{%1, %P0|%P0, %1}
2049    mov{q}\t{%1, %a0|%a0, %1}"
2050   [(set_attr "type" "imov")
2051    (set_attr "modrm" "0,*")
2052    (set_attr "length_address" "8,0")
2053    (set_attr "length_immediate" "0,*")
2054    (set_attr "memory" "store")
2055    (set_attr "mode" "DI")])
2057 (define_insn "*movabsdi_2_rex64"
2058   [(set (match_operand:DI 0 "register_operand" "=a,r")
2059         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2060   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2061   "@
2062    movabs{q}\t{%P1, %0|%0, %P1}
2063    mov{q}\t{%a1, %0|%0, %a1}"
2064   [(set_attr "type" "imov")
2065    (set_attr "modrm" "0,*")
2066    (set_attr "length_address" "8,0")
2067    (set_attr "length_immediate" "0")
2068    (set_attr "memory" "load")
2069    (set_attr "mode" "DI")])
2071 ;; Convert impossible stores of immediate to existing instructions.
2072 ;; First try to get scratch register and go through it.  In case this
2073 ;; fails, move by 32bit parts.
2074 (define_peephole2
2075   [(match_scratch:DI 2 "r")
2076    (set (match_operand:DI 0 "memory_operand" "")
2077         (match_operand:DI 1 "immediate_operand" ""))]
2078   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079    && !x86_64_immediate_operand (operands[1], DImode)"
2080   [(set (match_dup 2) (match_dup 1))
2081    (set (match_dup 0) (match_dup 2))]
2082   "")
2084 ;; We need to define this as both peepholer and splitter for case
2085 ;; peephole2 pass is not run.
2086 ;; "&& 1" is needed to keep it from matching the previous pattern.
2087 (define_peephole2
2088   [(set (match_operand:DI 0 "memory_operand" "")
2089         (match_operand:DI 1 "immediate_operand" ""))]
2090   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2092   [(set (match_dup 2) (match_dup 3))
2093    (set (match_dup 4) (match_dup 5))]
2094   "split_di (operands, 2, operands + 2, operands + 4);")
2096 (define_split
2097   [(set (match_operand:DI 0 "memory_operand" "")
2098         (match_operand:DI 1 "immediate_operand" ""))]
2099   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2100                     ? flow2_completed : reload_completed)
2101    && !symbolic_operand (operands[1], DImode)
2102    && !x86_64_immediate_operand (operands[1], DImode)"
2103   [(set (match_dup 2) (match_dup 3))
2104    (set (match_dup 4) (match_dup 5))]
2105   "split_di (operands, 2, operands + 2, operands + 4);")
2107 (define_insn "*swapdi_rex64"
2108   [(set (match_operand:DI 0 "register_operand" "+r")
2109         (match_operand:DI 1 "register_operand" "+r"))
2110    (set (match_dup 1)
2111         (match_dup 0))]
2112   "TARGET_64BIT"
2113   "xchg{q}\t%1, %0"
2114   [(set_attr "type" "imov")
2115    (set_attr "mode" "DI")
2116    (set_attr "pent_pair" "np")
2117    (set_attr "athlon_decode" "vector")])
2119 (define_expand "movti"
2120   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2121         (match_operand:TI 1 "nonimmediate_operand" ""))]
2122   "TARGET_SSE || TARGET_64BIT"
2124   if (TARGET_64BIT)
2125     ix86_expand_move (TImode, operands);
2126   else
2127     ix86_expand_vector_move (TImode, operands);
2128   DONE;
2131 (define_insn "*movti_internal"
2132   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2133         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2134   "TARGET_SSE && !TARGET_64BIT
2135    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2137   switch (which_alternative)
2138     {
2139     case 0:
2140       if (get_attr_mode (insn) == MODE_V4SF)
2141         return "xorps\t%0, %0";
2142       else
2143         return "pxor\t%0, %0";
2144     case 1:
2145     case 2:
2146       if (get_attr_mode (insn) == MODE_V4SF)
2147         return "movaps\t{%1, %0|%0, %1}";
2148       else
2149         return "movdqa\t{%1, %0|%0, %1}";
2150     default:
2151       gcc_unreachable ();
2152     }
2154   [(set_attr "type" "sselog1,ssemov,ssemov")
2155    (set (attr "mode")
2156         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2157                     (ne (symbol_ref "optimize_size") (const_int 0)))
2158                  (const_string "V4SF")
2159                (and (eq_attr "alternative" "2")
2160                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2161                         (const_int 0)))
2162                  (const_string "V4SF")]
2163               (const_string "TI")))])
2165 (define_insn "*movti_rex64"
2166   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2167         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2168   "TARGET_64BIT
2169    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2171   switch (which_alternative)
2172     {
2173     case 0:
2174     case 1:
2175       return "#";
2176     case 2:
2177       if (get_attr_mode (insn) == MODE_V4SF)
2178         return "xorps\t%0, %0";
2179       else
2180         return "pxor\t%0, %0";
2181     case 3:
2182     case 4:
2183       if (get_attr_mode (insn) == MODE_V4SF)
2184         return "movaps\t{%1, %0|%0, %1}";
2185       else
2186         return "movdqa\t{%1, %0|%0, %1}";
2187     default:
2188       gcc_unreachable ();
2189     }
2191   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2192    (set (attr "mode")
2193         (cond [(eq_attr "alternative" "2,3")
2194                  (if_then_else
2195                    (ne (symbol_ref "optimize_size")
2196                        (const_int 0))
2197                    (const_string "V4SF")
2198                    (const_string "TI"))
2199                (eq_attr "alternative" "4")
2200                  (if_then_else
2201                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2202                             (const_int 0))
2203                         (ne (symbol_ref "optimize_size")
2204                             (const_int 0)))
2205                    (const_string "V4SF")
2206                    (const_string "TI"))]
2207                (const_string "DI")))])
2209 (define_split
2210   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2211         (match_operand:TI 1 "general_operand" ""))]
2212   "reload_completed && !SSE_REG_P (operands[0])
2213    && !SSE_REG_P (operands[1])"
2214   [(const_int 0)]
2215   "ix86_split_long_move (operands); DONE;")
2217 (define_expand "movsf"
2218   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2219         (match_operand:SF 1 "general_operand" ""))]
2220   ""
2221   "ix86_expand_move (SFmode, operands); DONE;")
2223 (define_insn "*pushsf"
2224   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2225         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2226   "!TARGET_64BIT"
2228   /* Anything else should be already split before reg-stack.  */
2229   gcc_assert (which_alternative == 1);
2230   return "push{l}\t%1";
2232   [(set_attr "type" "multi,push,multi")
2233    (set_attr "unit" "i387,*,*")
2234    (set_attr "mode" "SF,SI,SF")])
2236 (define_insn "*pushsf_rex64"
2237   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2238         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2239   "TARGET_64BIT"
2241   /* Anything else should be already split before reg-stack.  */
2242   gcc_assert (which_alternative == 1);
2243   return "push{q}\t%q1";
2245   [(set_attr "type" "multi,push,multi")
2246    (set_attr "unit" "i387,*,*")
2247    (set_attr "mode" "SF,DI,SF")])
2249 (define_split
2250   [(set (match_operand:SF 0 "push_operand" "")
2251         (match_operand:SF 1 "memory_operand" ""))]
2252   "reload_completed
2253    && GET_CODE (operands[1]) == MEM
2254    && constant_pool_reference_p (operands[1])"
2255   [(set (match_dup 0)
2256         (match_dup 1))]
2257   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2260 ;; %%% Kill this when call knows how to work this out.
2261 (define_split
2262   [(set (match_operand:SF 0 "push_operand" "")
2263         (match_operand:SF 1 "any_fp_register_operand" ""))]
2264   "!TARGET_64BIT"
2265   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2266    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2268 (define_split
2269   [(set (match_operand:SF 0 "push_operand" "")
2270         (match_operand:SF 1 "any_fp_register_operand" ""))]
2271   "TARGET_64BIT"
2272   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2273    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2275 (define_insn "*movsf_1"
2276   [(set (match_operand:SF 0 "nonimmediate_operand"
2277           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2278         (match_operand:SF 1 "general_operand"
2279           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2280   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2281    && (reload_in_progress || reload_completed
2282        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2283        || GET_CODE (operands[1]) != CONST_DOUBLE
2284        || memory_operand (operands[0], SFmode))" 
2286   switch (which_alternative)
2287     {
2288     case 0:
2289       return output_387_reg_move (insn, operands);
2291     case 1:
2292       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293         return "fstp%z0\t%y0";
2294       else
2295         return "fst%z0\t%y0";
2297     case 2:
2298       return standard_80387_constant_opcode (operands[1]);
2300     case 3:
2301     case 4:
2302       return "mov{l}\t{%1, %0|%0, %1}";
2303     case 5:
2304       if (get_attr_mode (insn) == MODE_TI)
2305         return "pxor\t%0, %0";
2306       else
2307         return "xorps\t%0, %0";
2308     case 6:
2309       if (get_attr_mode (insn) == MODE_V4SF)
2310         return "movaps\t{%1, %0|%0, %1}";
2311       else
2312         return "movss\t{%1, %0|%0, %1}";
2313     case 7:
2314     case 8:
2315       return "movss\t{%1, %0|%0, %1}";
2317     case 9:
2318     case 10:
2319       return "movd\t{%1, %0|%0, %1}";
2321     case 11:
2322       return "movq\t{%1, %0|%0, %1}";
2324     default:
2325       gcc_unreachable ();
2326     }
2328   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2329    (set (attr "mode")
2330         (cond [(eq_attr "alternative" "3,4,9,10")
2331                  (const_string "SI")
2332                (eq_attr "alternative" "5")
2333                  (if_then_else
2334                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2335                                  (const_int 0))
2336                              (ne (symbol_ref "TARGET_SSE2")
2337                                  (const_int 0)))
2338                         (eq (symbol_ref "optimize_size")
2339                             (const_int 0)))
2340                    (const_string "TI")
2341                    (const_string "V4SF"))
2342                /* For architectures resolving dependencies on
2343                   whole SSE registers use APS move to break dependency
2344                   chains, otherwise use short move to avoid extra work. 
2346                   Do the same for architectures resolving dependencies on
2347                   the parts.  While in DF mode it is better to always handle
2348                   just register parts, the SF mode is different due to lack
2349                   of instructions to load just part of the register.  It is
2350                   better to maintain the whole registers in single format
2351                   to avoid problems on using packed logical operations.  */
2352                (eq_attr "alternative" "6")
2353                  (if_then_else
2354                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2355                             (const_int 0))
2356                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2357                             (const_int 0)))
2358                    (const_string "V4SF")
2359                    (const_string "SF"))
2360                (eq_attr "alternative" "11")
2361                  (const_string "DI")]
2362                (const_string "SF")))])
2364 (define_insn "*swapsf"
2365   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2366         (match_operand:SF 1 "fp_register_operand" "+f"))
2367    (set (match_dup 1)
2368         (match_dup 0))]
2369   "reload_completed || TARGET_80387"
2371   if (STACK_TOP_P (operands[0]))
2372     return "fxch\t%1";
2373   else
2374     return "fxch\t%0";
2376   [(set_attr "type" "fxch")
2377    (set_attr "mode" "SF")])
2379 (define_expand "movdf"
2380   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2381         (match_operand:DF 1 "general_operand" ""))]
2382   ""
2383   "ix86_expand_move (DFmode, operands); DONE;")
2385 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2386 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2387 ;; On the average, pushdf using integers can be still shorter.  Allow this
2388 ;; pattern for optimize_size too.
2390 (define_insn "*pushdf_nointeger"
2391   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2392         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2393   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2395   /* This insn should be already split before reg-stack.  */
2396   gcc_unreachable ();
2398   [(set_attr "type" "multi")
2399    (set_attr "unit" "i387,*,*,*")
2400    (set_attr "mode" "DF,SI,SI,DF")])
2402 (define_insn "*pushdf_integer"
2403   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2404         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2405   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2407   /* This insn should be already split before reg-stack.  */
2408   gcc_unreachable ();
2410   [(set_attr "type" "multi")
2411    (set_attr "unit" "i387,*,*")
2412    (set_attr "mode" "DF,SI,DF")])
2414 ;; %%% Kill this when call knows how to work this out.
2415 (define_split
2416   [(set (match_operand:DF 0 "push_operand" "")
2417         (match_operand:DF 1 "any_fp_register_operand" ""))]
2418   "!TARGET_64BIT && reload_completed"
2419   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2420    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2421   "")
2423 (define_split
2424   [(set (match_operand:DF 0 "push_operand" "")
2425         (match_operand:DF 1 "any_fp_register_operand" ""))]
2426   "TARGET_64BIT && reload_completed"
2427   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2428    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2429   "")
2431 (define_split
2432   [(set (match_operand:DF 0 "push_operand" "")
2433         (match_operand:DF 1 "general_operand" ""))]
2434   "reload_completed"
2435   [(const_int 0)]
2436   "ix86_split_long_move (operands); DONE;")
2438 ;; Moving is usually shorter when only FP registers are used. This separate
2439 ;; movdf pattern avoids the use of integer registers for FP operations
2440 ;; when optimizing for size.
2442 (define_insn "*movdf_nointeger"
2443   [(set (match_operand:DF 0 "nonimmediate_operand"
2444                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2445         (match_operand:DF 1 "general_operand"
2446                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2447   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449    && (reload_in_progress || reload_completed
2450        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451        || GET_CODE (operands[1]) != CONST_DOUBLE
2452        || memory_operand (operands[0], DFmode))" 
2454   switch (which_alternative)
2455     {
2456     case 0:
2457       return output_387_reg_move (insn, operands);
2459     case 1:
2460       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461         return "fstp%z0\t%y0";
2462       else
2463         return "fst%z0\t%y0";
2465     case 2:
2466       return standard_80387_constant_opcode (operands[1]);
2468     case 3:
2469     case 4:
2470       return "#";
2471     case 5:
2472       switch (get_attr_mode (insn))
2473         {
2474         case MODE_V4SF:
2475           return "xorps\t%0, %0";
2476         case MODE_V2DF:
2477           return "xorpd\t%0, %0";
2478         case MODE_TI:
2479           return "pxor\t%0, %0";
2480         default:
2481           gcc_unreachable ();
2482         }
2483     case 6:
2484     case 7:
2485     case 8:
2486       switch (get_attr_mode (insn))
2487         {
2488         case MODE_V4SF:
2489           return "movaps\t{%1, %0|%0, %1}";
2490         case MODE_V2DF:
2491           return "movapd\t{%1, %0|%0, %1}";
2492         case MODE_TI:
2493           return "movdqa\t{%1, %0|%0, %1}";
2494         case MODE_DI:
2495           return "movq\t{%1, %0|%0, %1}";
2496         case MODE_DF:
2497           return "movsd\t{%1, %0|%0, %1}";
2498         case MODE_V1DF:
2499           return "movlpd\t{%1, %0|%0, %1}";
2500         case MODE_V2SF:
2501           return "movlps\t{%1, %0|%0, %1}";
2502         default:
2503           gcc_unreachable ();
2504         }
2506     default:
2507       gcc_unreachable ();
2508     }
2510   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2511    (set (attr "mode")
2512         (cond [(eq_attr "alternative" "0,1,2")
2513                  (const_string "DF")
2514                (eq_attr "alternative" "3,4")
2515                  (const_string "SI")
2517                /* For SSE1, we have many fewer alternatives.  */
2518                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2519                  (cond [(eq_attr "alternative" "5,6")
2520                           (const_string "V4SF")
2521                        ]
2522                    (const_string "V2SF"))
2524                /* xorps is one byte shorter.  */
2525                (eq_attr "alternative" "5")
2526                  (cond [(ne (symbol_ref "optimize_size")
2527                             (const_int 0))
2528                           (const_string "V4SF")
2529                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2530                             (const_int 0))
2531                           (const_string "TI")
2532                        ]
2533                        (const_string "V2DF"))
2535                /* For architectures resolving dependencies on
2536                   whole SSE registers use APD move to break dependency
2537                   chains, otherwise use short move to avoid extra work.
2539                   movaps encodes one byte shorter.  */
2540                (eq_attr "alternative" "6")
2541                  (cond
2542                    [(ne (symbol_ref "optimize_size")
2543                         (const_int 0))
2544                       (const_string "V4SF")
2545                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2546                         (const_int 0))
2547                       (const_string "V2DF")
2548                    ]
2549                    (const_string "DF"))
2550                /* For architectures resolving dependencies on register
2551                   parts we may avoid extra work to zero out upper part
2552                   of register.  */
2553                (eq_attr "alternative" "7")
2554                  (if_then_else
2555                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2556                        (const_int 0))
2557                    (const_string "V1DF")
2558                    (const_string "DF"))
2559               ]
2560               (const_string "DF")))])
2562 (define_insn "*movdf_integer"
2563   [(set (match_operand:DF 0 "nonimmediate_operand"
2564                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2565         (match_operand:DF 1 "general_operand"
2566                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2567   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2568    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2569    && (reload_in_progress || reload_completed
2570        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2571        || GET_CODE (operands[1]) != CONST_DOUBLE
2572        || memory_operand (operands[0], DFmode))" 
2574   switch (which_alternative)
2575     {
2576     case 0:
2577       return output_387_reg_move (insn, operands);
2579     case 1:
2580       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2581         return "fstp%z0\t%y0";
2582       else
2583         return "fst%z0\t%y0";
2585     case 2:
2586       return standard_80387_constant_opcode (operands[1]);
2588     case 3:
2589     case 4:
2590       return "#";
2592     case 5:
2593       switch (get_attr_mode (insn))
2594         {
2595         case MODE_V4SF:
2596           return "xorps\t%0, %0";
2597         case MODE_V2DF:
2598           return "xorpd\t%0, %0";
2599         case MODE_TI:
2600           return "pxor\t%0, %0";
2601         default:
2602           gcc_unreachable ();
2603         }
2604     case 6:
2605     case 7:
2606     case 8:
2607       switch (get_attr_mode (insn))
2608         {
2609         case MODE_V4SF:
2610           return "movaps\t{%1, %0|%0, %1}";
2611         case MODE_V2DF:
2612           return "movapd\t{%1, %0|%0, %1}";
2613         case MODE_TI:
2614           return "movdqa\t{%1, %0|%0, %1}";
2615         case MODE_DI:
2616           return "movq\t{%1, %0|%0, %1}";
2617         case MODE_DF:
2618           return "movsd\t{%1, %0|%0, %1}";
2619         case MODE_V1DF:
2620           return "movlpd\t{%1, %0|%0, %1}";
2621         case MODE_V2SF:
2622           return "movlps\t{%1, %0|%0, %1}";
2623         default:
2624           gcc_unreachable ();
2625         }
2627     default:
2628       gcc_unreachable();
2629     }
2631   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "0,1,2")
2634                  (const_string "DF")
2635                (eq_attr "alternative" "3,4")
2636                  (const_string "SI")
2638                /* For SSE1, we have many fewer alternatives.  */
2639                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2640                  (cond [(eq_attr "alternative" "5,6")
2641                           (const_string "V4SF")
2642                        ]
2643                    (const_string "V2SF"))
2645                /* xorps is one byte shorter.  */
2646                (eq_attr "alternative" "5")
2647                  (cond [(ne (symbol_ref "optimize_size")
2648                             (const_int 0))
2649                           (const_string "V4SF")
2650                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2651                             (const_int 0))
2652                           (const_string "TI")
2653                        ]
2654                        (const_string "V2DF"))
2656                /* For architectures resolving dependencies on
2657                   whole SSE registers use APD move to break dependency
2658                   chains, otherwise use short move to avoid extra work.
2660                   movaps encodes one byte shorter.  */
2661                (eq_attr "alternative" "6")
2662                  (cond
2663                    [(ne (symbol_ref "optimize_size")
2664                         (const_int 0))
2665                       (const_string "V4SF")
2666                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667                         (const_int 0))
2668                       (const_string "V2DF")
2669                    ]
2670                    (const_string "DF"))
2671                /* For architectures resolving dependencies on register
2672                   parts we may avoid extra work to zero out upper part
2673                   of register.  */
2674                (eq_attr "alternative" "7")
2675                  (if_then_else
2676                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677                        (const_int 0))
2678                    (const_string "V1DF")
2679                    (const_string "DF"))
2680               ]
2681               (const_string "DF")))])
2683 (define_split
2684   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2685         (match_operand:DF 1 "general_operand" ""))]
2686   "reload_completed
2687    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2688    && ! (ANY_FP_REG_P (operands[0]) || 
2689          (GET_CODE (operands[0]) == SUBREG
2690           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2691    && ! (ANY_FP_REG_P (operands[1]) || 
2692          (GET_CODE (operands[1]) == SUBREG
2693           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2694   [(const_int 0)]
2695   "ix86_split_long_move (operands); DONE;")
2697 (define_insn "*swapdf"
2698   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2699         (match_operand:DF 1 "fp_register_operand" "+f"))
2700    (set (match_dup 1)
2701         (match_dup 0))]
2702   "reload_completed || TARGET_80387"
2704   if (STACK_TOP_P (operands[0]))
2705     return "fxch\t%1";
2706   else
2707     return "fxch\t%0";
2709   [(set_attr "type" "fxch")
2710    (set_attr "mode" "DF")])
2712 (define_expand "movxf"
2713   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2714         (match_operand:XF 1 "general_operand" ""))]
2715   ""
2716   "ix86_expand_move (XFmode, operands); DONE;")
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2720 ;; Pushing using integer instructions is longer except for constants
2721 ;; and direct memory references.
2722 ;; (assuming that any given constant is pushed only once, but this ought to be
2723 ;;  handled elsewhere).
2725 (define_insn "*pushxf_nointeger"
2726   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2727         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2728   "optimize_size"
2730   /* This insn should be already split before reg-stack.  */
2731   gcc_unreachable ();
2733   [(set_attr "type" "multi")
2734    (set_attr "unit" "i387,*,*")
2735    (set_attr "mode" "XF,SI,SI")])
2737 (define_insn "*pushxf_integer"
2738   [(set (match_operand:XF 0 "push_operand" "=<,<")
2739         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2740   "!optimize_size"
2742   /* This insn should be already split before reg-stack.  */
2743   gcc_unreachable ();
2745   [(set_attr "type" "multi")
2746    (set_attr "unit" "i387,*")
2747    (set_attr "mode" "XF,SI")])
2749 (define_split
2750   [(set (match_operand 0 "push_operand" "")
2751         (match_operand 1 "general_operand" ""))]
2752   "reload_completed
2753    && (GET_MODE (operands[0]) == XFmode
2754        || GET_MODE (operands[0]) == DFmode)
2755    && !ANY_FP_REG_P (operands[1])"
2756   [(const_int 0)]
2757   "ix86_split_long_move (operands); DONE;")
2759 (define_split
2760   [(set (match_operand:XF 0 "push_operand" "")
2761         (match_operand:XF 1 "any_fp_register_operand" ""))]
2762   "!TARGET_64BIT"
2763   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2764    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2765   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2767 (define_split
2768   [(set (match_operand:XF 0 "push_operand" "")
2769         (match_operand:XF 1 "any_fp_register_operand" ""))]
2770   "TARGET_64BIT"
2771   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2772    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2773   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779   "optimize_size
2780    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781    && (reload_in_progress || reload_completed
2782        || GET_CODE (operands[1]) != CONST_DOUBLE
2783        || memory_operand (operands[0], XFmode))" 
2785   switch (which_alternative)
2786     {
2787     case 0:
2788       return output_387_reg_move (insn, operands);
2790     case 1:
2791       /* There is no non-popping store to memory for XFmode.  So if
2792          we need one, follow the store with a load.  */
2793       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2794         return "fstp%z0\t%y0\;fld%z0\t%y0";
2795       else
2796         return "fstp%z0\t%y0";
2798     case 2:
2799       return standard_80387_constant_opcode (operands[1]);
2801     case 3: case 4:
2802       return "#";
2803     default:
2804       gcc_unreachable ();
2805     }
2807   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808    (set_attr "mode" "XF,XF,XF,SI,SI")])
2810 (define_insn "*movxf_integer"
2811   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2812         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2813   "!optimize_size
2814    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815    && (reload_in_progress || reload_completed
2816        || GET_CODE (operands[1]) != CONST_DOUBLE
2817        || memory_operand (operands[0], XFmode))" 
2819   switch (which_alternative)
2820     {
2821     case 0:
2822       return output_387_reg_move (insn, operands);
2824     case 1:
2825       /* There is no non-popping store to memory for XFmode.  So if
2826          we need one, follow the store with a load.  */
2827       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2828         return "fstp%z0\t%y0\;fld%z0\t%y0";
2829       else
2830         return "fstp%z0\t%y0";
2832     case 2:
2833       return standard_80387_constant_opcode (operands[1]);
2835     case 3: case 4:
2836       return "#";
2838     default:
2839       gcc_unreachable ();
2840     }
2842   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2843    (set_attr "mode" "XF,XF,XF,SI,SI")])
2845 (define_split
2846   [(set (match_operand 0 "nonimmediate_operand" "")
2847         (match_operand 1 "general_operand" ""))]
2848   "reload_completed
2849    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850    && GET_MODE (operands[0]) == XFmode
2851    && ! (ANY_FP_REG_P (operands[0]) || 
2852          (GET_CODE (operands[0]) == SUBREG
2853           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2854    && ! (ANY_FP_REG_P (operands[1]) || 
2855          (GET_CODE (operands[1]) == SUBREG
2856           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2857   [(const_int 0)]
2858   "ix86_split_long_move (operands); DONE;")
2860 (define_split
2861   [(set (match_operand 0 "register_operand" "")
2862         (match_operand 1 "memory_operand" ""))]
2863   "reload_completed
2864    && GET_CODE (operands[1]) == MEM
2865    && (GET_MODE (operands[0]) == XFmode
2866        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2867    && constant_pool_reference_p (operands[1])"
2868   [(set (match_dup 0) (match_dup 1))]
2870   rtx c = avoid_constant_pool_reference (operands[1]);
2871   rtx r = operands[0];
2873   if (GET_CODE (r) == SUBREG)
2874     r = SUBREG_REG (r);
2876   if (SSE_REG_P (r))
2877     {
2878       if (!standard_sse_constant_p (c))
2879         FAIL;
2880     }
2881   else if (FP_REG_P (r))
2882     {
2883       if (!standard_80387_constant_p (c))
2884         FAIL;
2885     }
2886   else if (MMX_REG_P (r))
2887     FAIL;
2889   operands[1] = c;
2892 (define_insn "swapxf"
2893   [(set (match_operand:XF 0 "register_operand" "+f")
2894         (match_operand:XF 1 "register_operand" "+f"))
2895    (set (match_dup 1)
2896         (match_dup 0))]
2897   "TARGET_80387"
2899   if (STACK_TOP_P (operands[0]))
2900     return "fxch\t%1";
2901   else
2902     return "fxch\t%0";
2904   [(set_attr "type" "fxch")
2905    (set_attr "mode" "XF")])
2907 (define_expand "movtf"
2908   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909         (match_operand:TF 1 "nonimmediate_operand" ""))]
2910   "TARGET_64BIT"
2912   ix86_expand_move (TFmode, operands);
2913   DONE;
2916 (define_insn "*movtf_internal"
2917   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2919   "TARGET_64BIT
2920    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2922   switch (which_alternative)
2923     {
2924     case 0:
2925     case 1:
2926       return "#";
2927     case 2:
2928       if (get_attr_mode (insn) == MODE_V4SF)
2929         return "xorps\t%0, %0";
2930       else
2931         return "pxor\t%0, %0";
2932     case 3:
2933     case 4:
2934       if (get_attr_mode (insn) == MODE_V4SF)
2935         return "movaps\t{%1, %0|%0, %1}";
2936       else
2937         return "movdqa\t{%1, %0|%0, %1}";
2938     default:
2939       gcc_unreachable ();
2940     }
2942   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2943    (set (attr "mode")
2944         (cond [(eq_attr "alternative" "2,3")
2945                  (if_then_else
2946                    (ne (symbol_ref "optimize_size")
2947                        (const_int 0))
2948                    (const_string "V4SF")
2949                    (const_string "TI"))
2950                (eq_attr "alternative" "4")
2951                  (if_then_else
2952                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2953                             (const_int 0))
2954                         (ne (symbol_ref "optimize_size")
2955                             (const_int 0)))
2956                    (const_string "V4SF")
2957                    (const_string "TI"))]
2958                (const_string "DI")))])
2960 (define_split
2961   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962         (match_operand:TF 1 "general_operand" ""))]
2963   "reload_completed && !SSE_REG_P (operands[0])
2964    && !SSE_REG_P (operands[1])"
2965   [(const_int 0)]
2966   "ix86_split_long_move (operands); DONE;")
2968 ;; Zero extension instructions
2970 (define_expand "zero_extendhisi2"
2971   [(set (match_operand:SI 0 "register_operand" "")
2972      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2973   ""
2975   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2976     {
2977       operands[1] = force_reg (HImode, operands[1]);
2978       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2979       DONE;
2980     }
2983 (define_insn "zero_extendhisi2_and"
2984   [(set (match_operand:SI 0 "register_operand" "=r")
2985      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986    (clobber (reg:CC FLAGS_REG))]
2987   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2988   "#"
2989   [(set_attr "type" "alu1")
2990    (set_attr "mode" "SI")])
2992 (define_split
2993   [(set (match_operand:SI 0 "register_operand" "")
2994         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995    (clobber (reg:CC FLAGS_REG))]
2996   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998               (clobber (reg:CC FLAGS_REG))])]
2999   "")
3001 (define_insn "*zero_extendhisi2_movzwl"
3002   [(set (match_operand:SI 0 "register_operand" "=r")
3003      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005   "movz{wl|x}\t{%1, %0|%0, %1}"
3006   [(set_attr "type" "imovx")
3007    (set_attr "mode" "SI")])
3009 (define_expand "zero_extendqihi2"
3010   [(parallel
3011     [(set (match_operand:HI 0 "register_operand" "")
3012        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013      (clobber (reg:CC FLAGS_REG))])]
3014   ""
3015   "")
3017 (define_insn "*zero_extendqihi2_and"
3018   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020    (clobber (reg:CC FLAGS_REG))]
3021   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3022   "#"
3023   [(set_attr "type" "alu1")
3024    (set_attr "mode" "HI")])
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027   [(set (match_operand:HI 0 "register_operand" "=r,r")
3028      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029    (clobber (reg:CC FLAGS_REG))]
3030   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3031   "#"
3032   [(set_attr "type" "imovx,alu1")
3033    (set_attr "mode" "HI")])
3035 ; zero extend to SImode here to avoid partial register stalls
3036 (define_insn "*zero_extendqihi2_movzbl"
3037   [(set (match_operand:HI 0 "register_operand" "=r")
3038      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3039   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3040   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3041   [(set_attr "type" "imovx")
3042    (set_attr "mode" "SI")])
3044 ;; For the movzbw case strip only the clobber
3045 (define_split
3046   [(set (match_operand:HI 0 "register_operand" "")
3047         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3048    (clobber (reg:CC FLAGS_REG))]
3049   "reload_completed 
3050    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3051    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3052   [(set (match_operand:HI 0 "register_operand" "")
3053         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3055 ;; When source and destination does not overlap, clear destination
3056 ;; first and then do the movb
3057 (define_split
3058   [(set (match_operand:HI 0 "register_operand" "")
3059         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3060    (clobber (reg:CC FLAGS_REG))]
3061   "reload_completed
3062    && ANY_QI_REG_P (operands[0])
3063    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3064    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3065   [(set (match_dup 0) (const_int 0))
3066    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3067   "operands[2] = gen_lowpart (QImode, operands[0]);")
3069 ;; Rest is handled by single and.
3070 (define_split
3071   [(set (match_operand:HI 0 "register_operand" "")
3072         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3073    (clobber (reg:CC FLAGS_REG))]
3074   "reload_completed
3075    && true_regnum (operands[0]) == true_regnum (operands[1])"
3076   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3077               (clobber (reg:CC FLAGS_REG))])]
3078   "")
3080 (define_expand "zero_extendqisi2"
3081   [(parallel
3082     [(set (match_operand:SI 0 "register_operand" "")
3083        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3084      (clobber (reg:CC FLAGS_REG))])]
3085   ""
3086   "")
3088 (define_insn "*zero_extendqisi2_and"
3089   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3090      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3091    (clobber (reg:CC FLAGS_REG))]
3092   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3093   "#"
3094   [(set_attr "type" "alu1")
3095    (set_attr "mode" "SI")])
3097 (define_insn "*zero_extendqisi2_movzbw_and"
3098   [(set (match_operand:SI 0 "register_operand" "=r,r")
3099      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3100    (clobber (reg:CC FLAGS_REG))]
3101   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3102   "#"
3103   [(set_attr "type" "imovx,alu1")
3104    (set_attr "mode" "SI")])
3106 (define_insn "*zero_extendqisi2_movzbw"
3107   [(set (match_operand:SI 0 "register_operand" "=r")
3108      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3109   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3110   "movz{bl|x}\t{%1, %0|%0, %1}"
3111   [(set_attr "type" "imovx")
3112    (set_attr "mode" "SI")])
3114 ;; For the movzbl case strip only the clobber
3115 (define_split
3116   [(set (match_operand:SI 0 "register_operand" "")
3117         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3118    (clobber (reg:CC FLAGS_REG))]
3119   "reload_completed 
3120    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3121    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3122   [(set (match_dup 0)
3123         (zero_extend:SI (match_dup 1)))])
3125 ;; When source and destination does not overlap, clear destination
3126 ;; first and then do the movb
3127 (define_split
3128   [(set (match_operand:SI 0 "register_operand" "")
3129         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3130    (clobber (reg:CC FLAGS_REG))]
3131   "reload_completed
3132    && ANY_QI_REG_P (operands[0])
3133    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3134    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3135    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3136   [(set (match_dup 0) (const_int 0))
3137    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3138   "operands[2] = gen_lowpart (QImode, operands[0]);")
3140 ;; Rest is handled by single and.
3141 (define_split
3142   [(set (match_operand:SI 0 "register_operand" "")
3143         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3144    (clobber (reg:CC FLAGS_REG))]
3145   "reload_completed
3146    && true_regnum (operands[0]) == true_regnum (operands[1])"
3147   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3148               (clobber (reg:CC FLAGS_REG))])]
3149   "")
3151 ;; %%% Kill me once multi-word ops are sane.
3152 (define_expand "zero_extendsidi2"
3153   [(set (match_operand:DI 0 "register_operand" "=r")
3154      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3155   ""
3156   "if (!TARGET_64BIT)
3157      {
3158        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3159        DONE;
3160      }
3161   ")
3163 (define_insn "zero_extendsidi2_32"
3164   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3165         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3166    (clobber (reg:CC FLAGS_REG))]
3167   "!TARGET_64BIT"
3168   "@
3169    #
3170    #
3171    #
3172    movd\t{%1, %0|%0, %1}
3173    movd\t{%1, %0|%0, %1}"
3174   [(set_attr "mode" "SI,SI,SI,DI,TI")
3175    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3177 (define_insn "zero_extendsidi2_rex64"
3178   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3179      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3180   "TARGET_64BIT"
3181   "@
3182    mov\t{%k1, %k0|%k0, %k1}
3183    #
3184    movd\t{%1, %0|%0, %1}
3185    movd\t{%1, %0|%0, %1}"
3186   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3187    (set_attr "mode" "SI,DI,SI,SI")])
3189 (define_split
3190   [(set (match_operand:DI 0 "memory_operand" "")
3191      (zero_extend:DI (match_dup 0)))]
3192   "TARGET_64BIT"
3193   [(set (match_dup 4) (const_int 0))]
3194   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3196 (define_split 
3197   [(set (match_operand:DI 0 "register_operand" "")
3198         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3199    (clobber (reg:CC FLAGS_REG))]
3200   "!TARGET_64BIT && reload_completed
3201    && true_regnum (operands[0]) == true_regnum (operands[1])"
3202   [(set (match_dup 4) (const_int 0))]
3203   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205 (define_split 
3206   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3207         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3208    (clobber (reg:CC FLAGS_REG))]
3209   "!TARGET_64BIT && reload_completed
3210    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3211   [(set (match_dup 3) (match_dup 1))
3212    (set (match_dup 4) (const_int 0))]
3213   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3215 (define_insn "zero_extendhidi2"
3216   [(set (match_operand:DI 0 "register_operand" "=r")
3217      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3218   "TARGET_64BIT"
3219   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3220   [(set_attr "type" "imovx")
3221    (set_attr "mode" "DI")])
3223 (define_insn "zero_extendqidi2"
3224   [(set (match_operand:DI 0 "register_operand" "=r")
3225      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3226   "TARGET_64BIT"
3227   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3228   [(set_attr "type" "imovx")
3229    (set_attr "mode" "DI")])
3231 ;; Sign extension instructions
3233 (define_expand "extendsidi2"
3234   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3235                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3236               (clobber (reg:CC FLAGS_REG))
3237               (clobber (match_scratch:SI 2 ""))])]
3238   ""
3240   if (TARGET_64BIT)
3241     {
3242       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3243       DONE;
3244     }
3247 (define_insn "*extendsidi2_1"
3248   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3249         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3250    (clobber (reg:CC FLAGS_REG))
3251    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3252   "!TARGET_64BIT"
3253   "#")
3255 (define_insn "extendsidi2_rex64"
3256   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3257         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3258   "TARGET_64BIT"
3259   "@
3260    {cltq|cdqe}
3261    movs{lq|x}\t{%1,%0|%0, %1}"
3262   [(set_attr "type" "imovx")
3263    (set_attr "mode" "DI")
3264    (set_attr "prefix_0f" "0")
3265    (set_attr "modrm" "0,1")])
3267 (define_insn "extendhidi2"
3268   [(set (match_operand:DI 0 "register_operand" "=r")
3269         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3270   "TARGET_64BIT"
3271   "movs{wq|x}\t{%1,%0|%0, %1}"
3272   [(set_attr "type" "imovx")
3273    (set_attr "mode" "DI")])
3275 (define_insn "extendqidi2"
3276   [(set (match_operand:DI 0 "register_operand" "=r")
3277         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278   "TARGET_64BIT"
3279   "movs{bq|x}\t{%1,%0|%0, %1}"
3280    [(set_attr "type" "imovx")
3281     (set_attr "mode" "DI")])
3283 ;; Extend to memory case when source register does die.
3284 (define_split 
3285   [(set (match_operand:DI 0 "memory_operand" "")
3286         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287    (clobber (reg:CC FLAGS_REG))
3288    (clobber (match_operand:SI 2 "register_operand" ""))]
3289   "(reload_completed
3290     && dead_or_set_p (insn, operands[1])
3291     && !reg_mentioned_p (operands[1], operands[0]))"
3292   [(set (match_dup 3) (match_dup 1))
3293    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3294               (clobber (reg:CC FLAGS_REG))])
3295    (set (match_dup 4) (match_dup 1))]
3296   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3298 ;; Extend to memory case when source register does not die.
3299 (define_split 
3300   [(set (match_operand:DI 0 "memory_operand" "")
3301         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3302    (clobber (reg:CC FLAGS_REG))
3303    (clobber (match_operand:SI 2 "register_operand" ""))]
3304   "reload_completed"
3305   [(const_int 0)]
3307   split_di (&operands[0], 1, &operands[3], &operands[4]);
3309   emit_move_insn (operands[3], operands[1]);
3311   /* Generate a cltd if possible and doing so it profitable.  */
3312   if (true_regnum (operands[1]) == 0
3313       && true_regnum (operands[2]) == 1
3314       && (optimize_size || TARGET_USE_CLTD))
3315     {
3316       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3317     }
3318   else
3319     {
3320       emit_move_insn (operands[2], operands[1]);
3321       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3322     }
3323   emit_move_insn (operands[4], operands[2]);
3324   DONE;
3327 ;; Extend to register case.  Optimize case where source and destination
3328 ;; registers match and cases where we can use cltd.
3329 (define_split 
3330   [(set (match_operand:DI 0 "register_operand" "")
3331         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332    (clobber (reg:CC FLAGS_REG))
3333    (clobber (match_scratch:SI 2 ""))]
3334   "reload_completed"
3335   [(const_int 0)]
3337   split_di (&operands[0], 1, &operands[3], &operands[4]);
3339   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3340     emit_move_insn (operands[3], operands[1]);
3342   /* Generate a cltd if possible and doing so it profitable.  */
3343   if (true_regnum (operands[3]) == 0
3344       && (optimize_size || TARGET_USE_CLTD))
3345     {
3346       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3347       DONE;
3348     }
3350   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3351     emit_move_insn (operands[4], operands[1]);
3353   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3354   DONE;
3357 (define_insn "extendhisi2"
3358   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3359         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3360   ""
3362   switch (get_attr_prefix_0f (insn))
3363     {
3364     case 0:
3365       return "{cwtl|cwde}";
3366     default:
3367       return "movs{wl|x}\t{%1,%0|%0, %1}";
3368     }
3370   [(set_attr "type" "imovx")
3371    (set_attr "mode" "SI")
3372    (set (attr "prefix_0f")
3373      ;; movsx is short decodable while cwtl is vector decoded.
3374      (if_then_else (and (eq_attr "cpu" "!k6")
3375                         (eq_attr "alternative" "0"))
3376         (const_string "0")
3377         (const_string "1")))
3378    (set (attr "modrm")
3379      (if_then_else (eq_attr "prefix_0f" "0")
3380         (const_string "0")
3381         (const_string "1")))])
3383 (define_insn "*extendhisi2_zext"
3384   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3385         (zero_extend:DI
3386           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3387   "TARGET_64BIT"
3389   switch (get_attr_prefix_0f (insn))
3390     {
3391     case 0:
3392       return "{cwtl|cwde}";
3393     default:
3394       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3395     }
3397   [(set_attr "type" "imovx")
3398    (set_attr "mode" "SI")
3399    (set (attr "prefix_0f")
3400      ;; movsx is short decodable while cwtl is vector decoded.
3401      (if_then_else (and (eq_attr "cpu" "!k6")
3402                         (eq_attr "alternative" "0"))
3403         (const_string "0")
3404         (const_string "1")))
3405    (set (attr "modrm")
3406      (if_then_else (eq_attr "prefix_0f" "0")
3407         (const_string "0")
3408         (const_string "1")))])
3410 (define_insn "extendqihi2"
3411   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3412         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3413   ""
3415   switch (get_attr_prefix_0f (insn))
3416     {
3417     case 0:
3418       return "{cbtw|cbw}";
3419     default:
3420       return "movs{bw|x}\t{%1,%0|%0, %1}";
3421     }
3423   [(set_attr "type" "imovx")
3424    (set_attr "mode" "HI")
3425    (set (attr "prefix_0f")
3426      ;; movsx is short decodable while cwtl is vector decoded.
3427      (if_then_else (and (eq_attr "cpu" "!k6")
3428                         (eq_attr "alternative" "0"))
3429         (const_string "0")
3430         (const_string "1")))
3431    (set (attr "modrm")
3432      (if_then_else (eq_attr "prefix_0f" "0")
3433         (const_string "0")
3434         (const_string "1")))])
3436 (define_insn "extendqisi2"
3437   [(set (match_operand:SI 0 "register_operand" "=r")
3438         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3439   ""
3440   "movs{bl|x}\t{%1,%0|%0, %1}"
3441    [(set_attr "type" "imovx")
3442     (set_attr "mode" "SI")])
3444 (define_insn "*extendqisi2_zext"
3445   [(set (match_operand:DI 0 "register_operand" "=r")
3446         (zero_extend:DI
3447           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3448   "TARGET_64BIT"
3449   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3450    [(set_attr "type" "imovx")
3451     (set_attr "mode" "SI")])
3453 ;; Conversions between float and double.
3455 ;; These are all no-ops in the model used for the 80387.  So just
3456 ;; emit moves.
3458 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3459 (define_insn "*dummy_extendsfdf2"
3460   [(set (match_operand:DF 0 "push_operand" "=<")
3461         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3462   "0"
3463   "#")
3465 (define_split
3466   [(set (match_operand:DF 0 "push_operand" "")
3467         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3468   "!TARGET_64BIT"
3469   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3470    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3472 (define_split
3473   [(set (match_operand:DF 0 "push_operand" "")
3474         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3475   "TARGET_64BIT"
3476   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3477    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3479 (define_insn "*dummy_extendsfxf2"
3480   [(set (match_operand:XF 0 "push_operand" "=<")
3481         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3482   "0"
3483   "#")
3485 (define_split
3486   [(set (match_operand:XF 0 "push_operand" "")
3487         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3488   ""
3489   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3490    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3491   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3493 (define_split
3494   [(set (match_operand:XF 0 "push_operand" "")
3495         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3496   "TARGET_64BIT"
3497   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3498    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3499   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3501 (define_split
3502   [(set (match_operand:XF 0 "push_operand" "")
3503         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3504   ""
3505   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3506    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3507   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3509 (define_split
3510   [(set (match_operand:XF 0 "push_operand" "")
3511         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3512   "TARGET_64BIT"
3513   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3514    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3515   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3517 (define_expand "extendsfdf2"
3518   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3519         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3520   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3522   /* ??? Needed for compress_float_constant since all fp constants
3523      are LEGITIMATE_CONSTANT_P.  */
3524   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3525     {
3526       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3527           && standard_80387_constant_p (operands[1]) > 0)
3528         {
3529           operands[1] = simplify_const_unary_operation
3530             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3531           emit_move_insn_1 (operands[0], operands[1]);
3532           DONE;
3533         }
3534       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3535     }
3536   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3537     operands[1] = force_reg (SFmode, operands[1]);
3540 (define_insn "*extendsfdf2_mixed"
3541   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3542         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3543   "TARGET_SSE2 && TARGET_MIX_SSE_I387
3544    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3546   switch (which_alternative)
3547     {
3548     case 0:
3549       return output_387_reg_move (insn, operands);
3551     case 1:
3552       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3553         return "fstp%z0\t%y0";
3554       else
3555         return "fst%z0\t%y0";
3557     case 2:
3558       return "cvtss2sd\t{%1, %0|%0, %1}";
3560     default:
3561       gcc_unreachable ();
3562     }
3564   [(set_attr "type" "fmov,fmov,ssecvt")
3565    (set_attr "mode" "SF,XF,DF")])
3567 (define_insn "*extendsfdf2_sse"
3568   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3569         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3570   "TARGET_SSE2 && TARGET_SSE_MATH
3571    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3572   "cvtss2sd\t{%1, %0|%0, %1}"
3573   [(set_attr "type" "ssecvt")
3574    (set_attr "mode" "DF")])
3576 (define_insn "*extendsfdf2_i387"
3577   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3578         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3579   "TARGET_80387
3580    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3582   switch (which_alternative)
3583     {
3584     case 0:
3585       return output_387_reg_move (insn, operands);
3587     case 1:
3588       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3589         return "fstp%z0\t%y0";
3590       else
3591         return "fst%z0\t%y0";
3593     default:
3594       gcc_unreachable ();
3595     }
3597   [(set_attr "type" "fmov")
3598    (set_attr "mode" "SF,XF")])
3600 (define_expand "extendsfxf2"
3601   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3602         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3603   "TARGET_80387"
3605   /* ??? Needed for compress_float_constant since all fp constants
3606      are LEGITIMATE_CONSTANT_P.  */
3607   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3608     {
3609       if (standard_80387_constant_p (operands[1]) > 0)
3610         {
3611           operands[1] = simplify_const_unary_operation
3612             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3613           emit_move_insn_1 (operands[0], operands[1]);
3614           DONE;
3615         }
3616       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3617     }
3618   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3619     operands[1] = force_reg (SFmode, operands[1]);
3622 (define_insn "*extendsfxf2_i387"
3623   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3624         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3625   "TARGET_80387
3626    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3628   switch (which_alternative)
3629     {
3630     case 0:
3631       return output_387_reg_move (insn, operands);
3633     case 1:
3634       /* There is no non-popping store to memory for XFmode.  So if
3635          we need one, follow the store with a load.  */
3636       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637         return "fstp%z0\t%y0";
3638       else
3639         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3641     default:
3642       gcc_unreachable ();
3643     }
3645   [(set_attr "type" "fmov")
3646    (set_attr "mode" "SF,XF")])
3648 (define_expand "extenddfxf2"
3649   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3650         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3651   "TARGET_80387"
3653   /* ??? Needed for compress_float_constant since all fp constants
3654      are LEGITIMATE_CONSTANT_P.  */
3655   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3656     {
3657       if (standard_80387_constant_p (operands[1]) > 0)
3658         {
3659           operands[1] = simplify_const_unary_operation
3660             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3661           emit_move_insn_1 (operands[0], operands[1]);
3662           DONE;
3663         }
3664       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3665     }
3666   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3667     operands[1] = force_reg (DFmode, operands[1]);
3670 (define_insn "*extenddfxf2_i387"
3671   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3672         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3673   "TARGET_80387
3674    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3676   switch (which_alternative)
3677     {
3678     case 0:
3679       return output_387_reg_move (insn, operands);
3681     case 1:
3682       /* There is no non-popping store to memory for XFmode.  So if
3683          we need one, follow the store with a load.  */
3684       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3686       else
3687         return "fstp%z0\t%y0";
3689     default:
3690       gcc_unreachable ();
3691     }
3693   [(set_attr "type" "fmov")
3694    (set_attr "mode" "DF,XF")])
3696 ;; %%% This seems bad bad news.
3697 ;; This cannot output into an f-reg because there is no way to be sure
3698 ;; of truncating in that case.  Otherwise this is just like a simple move
3699 ;; insn.  So we pretend we can output to a reg in order to get better
3700 ;; register preferencing, but we really use a stack slot.
3702 ;; Conversion from DFmode to SFmode.
3704 (define_expand "truncdfsf2"
3705   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3706         (float_truncate:SF
3707           (match_operand:DF 1 "nonimmediate_operand" "")))]
3708   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3710   if (MEM_P (operands[0]) && MEM_P (operands[1]))
3711     operands[1] = force_reg (DFmode, operands[1]);
3713   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3714     ;
3715   else if (flag_unsafe_math_optimizations)
3716     ;
3717   else
3718     {
3719       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3720       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3721       DONE;
3722     }
3725 (define_expand "truncdfsf2_with_temp"
3726   [(parallel [(set (match_operand:SF 0 "" "")
3727                    (float_truncate:SF (match_operand:DF 1 "" "")))
3728               (clobber (match_operand:SF 2 "" ""))])]
3729   "")
3731 (define_insn "*truncdfsf_fast_mixed"
3732   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3733         (float_truncate:SF
3734           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3735   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3737   switch (which_alternative)
3738     {
3739     case 0:
3740       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3741         return "fstp%z0\t%y0";
3742       else
3743         return "fst%z0\t%y0";
3744     case 1:
3745       return output_387_reg_move (insn, operands);
3746     case 2:
3747       return "cvtsd2ss\t{%1, %0|%0, %1}";
3748     default:
3749       gcc_unreachable ();
3750     }
3752   [(set_attr "type" "fmov,fmov,ssecvt")
3753    (set_attr "mode" "SF")])
3755 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3756 ;; because nothing we do here is unsafe.
3757 (define_insn "*truncdfsf_fast_sse"
3758   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3759         (float_truncate:SF
3760           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3761   "TARGET_SSE2 && TARGET_SSE_MATH"
3762   "cvtsd2ss\t{%1, %0|%0, %1}"
3763   [(set_attr "type" "ssecvt")
3764    (set_attr "mode" "SF")])
3766 (define_insn "*truncdfsf_fast_i387"
3767   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3768         (float_truncate:SF
3769           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3770   "TARGET_80387 && flag_unsafe_math_optimizations"
3771   "* return output_387_reg_move (insn, operands);"
3772   [(set_attr "type" "fmov")
3773    (set_attr "mode" "SF")])
3775 (define_insn "*truncdfsf_mixed"
3776   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3777         (float_truncate:SF
3778           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3779    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3780   "TARGET_MIX_SSE_I387"
3782   switch (which_alternative)
3783     {
3784     case 0:
3785       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786         return "fstp%z0\t%y0";
3787       else
3788         return "fst%z0\t%y0";
3789     case 1:
3790       return "#";
3791     case 2:
3792       return "cvtsd2ss\t{%1, %0|%0, %1}";
3793     default:
3794       gcc_unreachable ();
3795     }
3797   [(set_attr "type" "fmov,multi,ssecvt")
3798    (set_attr "unit" "*,i387,*")
3799    (set_attr "mode" "SF")])
3801 (define_insn "*truncdfsf_i387"
3802   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3803         (float_truncate:SF
3804           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3805    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3806   "TARGET_80387"
3808   switch (which_alternative)
3809     {
3810     case 0:
3811       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3812         return "fstp%z0\t%y0";
3813       else
3814         return "fst%z0\t%y0";
3815     case 1:
3816       return "#";
3817     default:
3818       gcc_unreachable ();
3819     }
3821   [(set_attr "type" "fmov,multi")
3822    (set_attr "unit" "*,i387")
3823    (set_attr "mode" "SF")])
3825 (define_insn "*truncdfsf2_i387_1"
3826   [(set (match_operand:SF 0 "memory_operand" "=m")
3827         (float_truncate:SF
3828           (match_operand:DF 1 "register_operand" "f")))]
3829   "TARGET_80387
3830    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3831    && !TARGET_MIX_SSE_I387"
3833   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834     return "fstp%z0\t%y0";
3835   else
3836     return "fst%z0\t%y0";
3838   [(set_attr "type" "fmov")
3839    (set_attr "mode" "SF")])
3841 (define_split
3842   [(set (match_operand:SF 0 "register_operand" "")
3843         (float_truncate:SF
3844          (match_operand:DF 1 "fp_register_operand" "")))
3845    (clobber (match_operand 2 "" ""))]
3846   "reload_completed"
3847   [(set (match_dup 2) (match_dup 1))
3848    (set (match_dup 0) (match_dup 2))]
3850   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3853 ;; Conversion from XFmode to SFmode.
3855 (define_expand "truncxfsf2"
3856   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3857                    (float_truncate:SF
3858                     (match_operand:XF 1 "register_operand" "")))
3859               (clobber (match_dup 2))])]
3860   "TARGET_80387"
3862   if (flag_unsafe_math_optimizations)
3863     {
3864       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3865       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3866       if (reg != operands[0])
3867         emit_move_insn (operands[0], reg);
3868       DONE;
3869     }
3870   else
3871     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3874 (define_insn "*truncxfsf2_mixed"
3875   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3876         (float_truncate:SF
3877          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3878    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3879   "TARGET_MIX_SSE_I387"
3881   gcc_assert (!which_alternative);
3882   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883     return "fstp%z0\t%y0";
3884   else
3885     return "fst%z0\t%y0";
3887   [(set_attr "type" "fmov,multi,multi,multi")
3888    (set_attr "unit" "*,i387,i387,i387")
3889    (set_attr "mode" "SF")])
3891 (define_insn "truncxfsf2_i387_noop"
3892   [(set (match_operand:SF 0 "register_operand" "=f")
3893         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3894   "TARGET_80387 && flag_unsafe_math_optimizations"
3896   return output_387_reg_move (insn, operands);
3898   [(set_attr "type" "fmov")
3899    (set_attr "mode" "SF")])
3901 (define_insn "*truncxfsf2_i387"
3902   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3903         (float_truncate:SF
3904          (match_operand:XF 1 "register_operand" "f,f,f")))
3905    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3906   "TARGET_80387"
3908   gcc_assert (!which_alternative);
3909   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910     return "fstp%z0\t%y0";
3911    else
3912      return "fst%z0\t%y0";
3914   [(set_attr "type" "fmov,multi,multi")
3915    (set_attr "unit" "*,i387,i387")
3916    (set_attr "mode" "SF")])
3918 (define_insn "*truncxfsf2_i387_1"
3919   [(set (match_operand:SF 0 "memory_operand" "=m")
3920         (float_truncate:SF
3921          (match_operand:XF 1 "register_operand" "f")))]
3922   "TARGET_80387"
3924   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3925     return "fstp%z0\t%y0";
3926   else
3927     return "fst%z0\t%y0";
3929   [(set_attr "type" "fmov")
3930    (set_attr "mode" "SF")])
3932 (define_split
3933   [(set (match_operand:SF 0 "register_operand" "")
3934         (float_truncate:SF
3935          (match_operand:XF 1 "register_operand" "")))
3936    (clobber (match_operand:SF 2 "memory_operand" ""))]
3937   "TARGET_80387 && reload_completed"
3938   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3939    (set (match_dup 0) (match_dup 2))]
3940   "")
3942 (define_split
3943   [(set (match_operand:SF 0 "memory_operand" "")
3944         (float_truncate:SF
3945          (match_operand:XF 1 "register_operand" "")))
3946    (clobber (match_operand:SF 2 "memory_operand" ""))]
3947   "TARGET_80387"
3948   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3949   "")
3951 ;; Conversion from XFmode to DFmode.
3953 (define_expand "truncxfdf2"
3954   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3955                    (float_truncate:DF
3956                     (match_operand:XF 1 "register_operand" "")))
3957               (clobber (match_dup 2))])]
3958   "TARGET_80387"
3960   if (flag_unsafe_math_optimizations)
3961     {
3962       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3963       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3964       if (reg != operands[0])
3965         emit_move_insn (operands[0], reg);
3966       DONE;
3967     }
3968   else
3969     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3972 (define_insn "*truncxfdf2_mixed"
3973   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3974         (float_truncate:DF
3975          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3976    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3977   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3979   gcc_assert (!which_alternative);
3980   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981     return "fstp%z0\t%y0";
3982   else
3983     return "fst%z0\t%y0";
3985   [(set_attr "type" "fmov,multi,multi,multi")
3986    (set_attr "unit" "*,i387,i387,i387")
3987    (set_attr "mode" "DF")])
3989 (define_insn "truncxfdf2_i387_noop"
3990   [(set (match_operand:DF 0 "register_operand" "=f")
3991         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3992   "TARGET_80387 && flag_unsafe_math_optimizations"
3994   return output_387_reg_move (insn, operands);
3996   [(set_attr "type" "fmov")
3997    (set_attr "mode" "DF")])
3999 (define_insn "*truncxfdf2_i387"
4000   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4001         (float_truncate:DF
4002          (match_operand:XF 1 "register_operand" "f,f,f")))
4003    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4004   "TARGET_80387"
4006   gcc_assert (!which_alternative);
4007   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008     return "fstp%z0\t%y0";
4009   else
4010     return "fst%z0\t%y0";
4012   [(set_attr "type" "fmov,multi,multi")
4013    (set_attr "unit" "*,i387,i387")
4014    (set_attr "mode" "DF")])
4016 (define_insn "*truncxfdf2_i387_1"
4017   [(set (match_operand:DF 0 "memory_operand" "=m")
4018         (float_truncate:DF
4019           (match_operand:XF 1 "register_operand" "f")))]
4020   "TARGET_80387"
4022   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4023     return "fstp%z0\t%y0";
4024   else
4025     return "fst%z0\t%y0";
4027   [(set_attr "type" "fmov")
4028    (set_attr "mode" "DF")])
4030 (define_split
4031   [(set (match_operand:DF 0 "register_operand" "")
4032         (float_truncate:DF
4033          (match_operand:XF 1 "register_operand" "")))
4034    (clobber (match_operand:DF 2 "memory_operand" ""))]
4035   "TARGET_80387 && reload_completed"
4036   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4037    (set (match_dup 0) (match_dup 2))]
4038   "")
4040 (define_split
4041   [(set (match_operand:DF 0 "memory_operand" "")
4042         (float_truncate:DF
4043          (match_operand:XF 1 "register_operand" "")))
4044    (clobber (match_operand:DF 2 "memory_operand" ""))]
4045   "TARGET_80387"
4046   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4047   "")
4049 ;; Signed conversion to DImode.
4051 (define_expand "fix_truncxfdi2"
4052   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4053                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4054               (clobber (reg:CC FLAGS_REG))])]
4055   "TARGET_80387"
4057   if (TARGET_FISTTP)
4058    {
4059      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4060      DONE;
4061    }
4064 (define_expand "fix_trunc<mode>di2"
4065   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4066                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4067               (clobber (reg:CC FLAGS_REG))])]
4068   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4070   if (TARGET_FISTTP
4071       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4072    {
4073      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4074      DONE;
4075    }
4076   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4077    {
4078      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4079      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4080      if (out != operands[0])
4081         emit_move_insn (operands[0], out);
4082      DONE;
4083    }
4086 ;; Signed conversion to SImode.
4088 (define_expand "fix_truncxfsi2"
4089   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4090                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4091               (clobber (reg:CC FLAGS_REG))])]
4092   "TARGET_80387"
4094   if (TARGET_FISTTP)
4095    {
4096      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4097      DONE;
4098    }
4101 (define_expand "fix_trunc<mode>si2"
4102   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4103                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4104               (clobber (reg:CC FLAGS_REG))])]
4105   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4107   if (TARGET_FISTTP
4108       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4109    {
4110      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4111      DONE;
4112    }
4113   if (SSE_FLOAT_MODE_P (<MODE>mode))
4114    {
4115      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4116      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4117      if (out != operands[0])
4118         emit_move_insn (operands[0], out);
4119      DONE;
4120    }
4123 ;; Signed conversion to HImode.
4125 (define_expand "fix_trunc<mode>hi2"
4126   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4127                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4128               (clobber (reg:CC FLAGS_REG))])]
4129   "TARGET_80387
4130    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4132   if (TARGET_FISTTP)
4133    {
4134      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4135      DONE;
4136    }
4139 ;; When SSE is available, it is always faster to use it!
4140 (define_insn "fix_truncsfdi_sse"
4141   [(set (match_operand:DI 0 "register_operand" "=r,r")
4142         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4143   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4144   "cvttss2si{q}\t{%1, %0|%0, %1}"
4145   [(set_attr "type" "sseicvt")
4146    (set_attr "mode" "SF")
4147    (set_attr "athlon_decode" "double,vector")])
4149 (define_insn "fix_truncdfdi_sse"
4150   [(set (match_operand:DI 0 "register_operand" "=r,r")
4151         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4152   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4153   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4154   [(set_attr "type" "sseicvt")
4155    (set_attr "mode" "DF")
4156    (set_attr "athlon_decode" "double,vector")])
4158 (define_insn "fix_truncsfsi_sse"
4159   [(set (match_operand:SI 0 "register_operand" "=r,r")
4160         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4161   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4162   "cvttss2si\t{%1, %0|%0, %1}"
4163   [(set_attr "type" "sseicvt")
4164    (set_attr "mode" "DF")
4165    (set_attr "athlon_decode" "double,vector")])
4167 (define_insn "fix_truncdfsi_sse"
4168   [(set (match_operand:SI 0 "register_operand" "=r,r")
4169         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4170   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171   "cvttsd2si\t{%1, %0|%0, %1}"
4172   [(set_attr "type" "sseicvt")
4173    (set_attr "mode" "DF")
4174    (set_attr "athlon_decode" "double,vector")])
4176 ;; Avoid vector decoded forms of the instruction.
4177 (define_peephole2
4178   [(match_scratch:DF 2 "Y")
4179    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4180         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4181   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4182   [(set (match_dup 2) (match_dup 1))
4183    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4184   "")
4186 (define_peephole2
4187   [(match_scratch:SF 2 "x")
4188    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4189         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4190   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4191   [(set (match_dup 2) (match_dup 1))
4192    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4193   "")
4195 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4196   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4197         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4198   "TARGET_FISTTP
4199    && FLOAT_MODE_P (GET_MODE (operands[1]))
4200    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201          && (TARGET_64BIT || <MODE>mode != DImode))
4202         && TARGET_SSE_MATH)
4203    && !(reload_completed || reload_in_progress)"
4204   "#"
4205   "&& 1"
4206   [(const_int 0)]
4208   if (memory_operand (operands[0], VOIDmode))
4209     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4210   else
4211     {
4212       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4213       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4214                                                             operands[1],
4215                                                             operands[2]));
4216     }
4217   DONE;
4219   [(set_attr "type" "fisttp")
4220    (set_attr "mode" "<MODE>")])
4222 (define_insn "fix_trunc<mode>_i387_fisttp"
4223   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4224         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4225    (clobber (match_scratch:XF 2 "=&1f"))]
4226   "TARGET_FISTTP
4227    && FLOAT_MODE_P (GET_MODE (operands[1]))
4228    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4229          && (TARGET_64BIT || <MODE>mode != DImode))
4230         && TARGET_SSE_MATH)"
4231   "* return output_fix_trunc (insn, operands, 1);"
4232   [(set_attr "type" "fisttp")
4233    (set_attr "mode" "<MODE>")])
4235 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4236   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4237         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4238    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4239    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4240   "TARGET_FISTTP
4241    && FLOAT_MODE_P (GET_MODE (operands[1]))
4242    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4243         && (TARGET_64BIT || <MODE>mode != DImode))
4244         && TARGET_SSE_MATH)"
4245   "#"
4246   [(set_attr "type" "fisttp")
4247    (set_attr "mode" "<MODE>")])
4249 (define_split
4250   [(set (match_operand:X87MODEI 0 "register_operand" "")
4251         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4252    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4253    (clobber (match_scratch 3 ""))]
4254   "reload_completed"
4255   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4256               (clobber (match_dup 3))])
4257    (set (match_dup 0) (match_dup 2))]
4258   "")
4260 (define_split
4261   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4262         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4263    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4264    (clobber (match_scratch 3 ""))]
4265   "reload_completed"
4266   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4267               (clobber (match_dup 3))])]
4268   "")
4270 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4271 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4272 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4273 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4274 ;; function in i386.c.
4275 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4276   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4277         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4278    (clobber (reg:CC FLAGS_REG))]
4279   "TARGET_80387 && !TARGET_FISTTP
4280    && FLOAT_MODE_P (GET_MODE (operands[1]))
4281    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4282          && (TARGET_64BIT || <MODE>mode != DImode))
4283    && !(reload_completed || reload_in_progress)"
4284   "#"
4285   "&& 1"
4286   [(const_int 0)]
4288   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4290   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4291   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4292   if (memory_operand (operands[0], VOIDmode))
4293     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4294                                          operands[2], operands[3]));
4295   else
4296     {
4297       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4298       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4299                                                      operands[2], operands[3],
4300                                                      operands[4]));
4301     }
4302   DONE;
4304   [(set_attr "type" "fistp")
4305    (set_attr "i387_cw" "trunc")
4306    (set_attr "mode" "<MODE>")])
4308 (define_insn "fix_truncdi_i387"
4309   [(set (match_operand:DI 0 "memory_operand" "=m")
4310         (fix:DI (match_operand 1 "register_operand" "f")))
4311    (use (match_operand:HI 2 "memory_operand" "m"))
4312    (use (match_operand:HI 3 "memory_operand" "m"))
4313    (clobber (match_scratch:XF 4 "=&1f"))]
4314   "TARGET_80387 && !TARGET_FISTTP
4315    && FLOAT_MODE_P (GET_MODE (operands[1]))
4316    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4317   "* return output_fix_trunc (insn, operands, 0);"
4318   [(set_attr "type" "fistp")
4319    (set_attr "i387_cw" "trunc")
4320    (set_attr "mode" "DI")])
4322 (define_insn "fix_truncdi_i387_with_temp"
4323   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4324         (fix:DI (match_operand 1 "register_operand" "f,f")))
4325    (use (match_operand:HI 2 "memory_operand" "m,m"))
4326    (use (match_operand:HI 3 "memory_operand" "m,m"))
4327    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4328    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4329   "TARGET_80387 && !TARGET_FISTTP
4330    && FLOAT_MODE_P (GET_MODE (operands[1]))
4331    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4332   "#"
4333   [(set_attr "type" "fistp")
4334    (set_attr "i387_cw" "trunc")
4335    (set_attr "mode" "DI")])
4337 (define_split 
4338   [(set (match_operand:DI 0 "register_operand" "")
4339         (fix:DI (match_operand 1 "register_operand" "")))
4340    (use (match_operand:HI 2 "memory_operand" ""))
4341    (use (match_operand:HI 3 "memory_operand" ""))
4342    (clobber (match_operand:DI 4 "memory_operand" ""))
4343    (clobber (match_scratch 5 ""))]
4344   "reload_completed"
4345   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4346               (use (match_dup 2))
4347               (use (match_dup 3))
4348               (clobber (match_dup 5))])
4349    (set (match_dup 0) (match_dup 4))]
4350   "")
4352 (define_split 
4353   [(set (match_operand:DI 0 "memory_operand" "")
4354         (fix:DI (match_operand 1 "register_operand" "")))
4355    (use (match_operand:HI 2 "memory_operand" ""))
4356    (use (match_operand:HI 3 "memory_operand" ""))
4357    (clobber (match_operand:DI 4 "memory_operand" ""))
4358    (clobber (match_scratch 5 ""))]
4359   "reload_completed"
4360   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4361               (use (match_dup 2))
4362               (use (match_dup 3))
4363               (clobber (match_dup 5))])]
4364   "")
4366 (define_insn "fix_trunc<mode>_i387"
4367   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4368         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4369    (use (match_operand:HI 2 "memory_operand" "m"))
4370    (use (match_operand:HI 3 "memory_operand" "m"))]
4371   "TARGET_80387 && !TARGET_FISTTP
4372    && FLOAT_MODE_P (GET_MODE (operands[1]))
4373    && !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" "<MODE>")])
4379 (define_insn "fix_trunc<mode>_i387_with_temp"
4380   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4381         (fix:X87MODEI12 (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:X87MODEI12 4 "memory_operand" "=m,m"))]
4385   "TARGET_80387 && !TARGET_FISTTP
4386    && FLOAT_MODE_P (GET_MODE (operands[1]))
4387    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4388   "#"
4389   [(set_attr "type" "fistp")
4390    (set_attr "i387_cw" "trunc")
4391    (set_attr "mode" "<MODE>")])
4393 (define_split 
4394   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4395         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4396    (use (match_operand:HI 2 "memory_operand" ""))
4397    (use (match_operand:HI 3 "memory_operand" ""))
4398    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4399   "reload_completed"
4400   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4401               (use (match_dup 2))
4402               (use (match_dup 3))])
4403    (set (match_dup 0) (match_dup 4))]
4404   "")
4406 (define_split 
4407   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4408         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4409    (use (match_operand:HI 2 "memory_operand" ""))
4410    (use (match_operand:HI 3 "memory_operand" ""))
4411    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4412   "reload_completed"
4413   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4414               (use (match_dup 2))
4415               (use (match_dup 3))])]
4416   "")
4418 (define_insn "x86_fnstcw_1"
4419   [(set (match_operand:HI 0 "memory_operand" "=m")
4420         (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4421   "TARGET_80387"
4422   "fnstcw\t%0"
4423   [(set_attr "length" "2")
4424    (set_attr "mode" "HI")
4425    (set_attr "unit" "i387")])
4427 (define_insn "x86_fldcw_1"
4428   [(set (reg:HI FPSR_REG)
4429         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4430   "TARGET_80387"
4431   "fldcw\t%0"
4432   [(set_attr "length" "2")
4433    (set_attr "mode" "HI")
4434    (set_attr "unit" "i387")
4435    (set_attr "athlon_decode" "vector")])
4437 ;; Conversion between fixed point and floating point.
4439 ;; Even though we only accept memory inputs, the backend _really_
4440 ;; wants to be able to do this between registers.
4442 (define_expand "floathisf2"
4443   [(set (match_operand:SF 0 "register_operand" "")
4444         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4445   "TARGET_80387 || TARGET_SSE_MATH"
4447   if (TARGET_SSE_MATH)
4448     {
4449       emit_insn (gen_floatsisf2 (operands[0],
4450                                  convert_to_mode (SImode, operands[1], 0)));
4451       DONE;
4452     }
4455 (define_insn "*floathisf2_i387"
4456   [(set (match_operand:SF 0 "register_operand" "=f,f")
4457         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4458   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4459   "@
4460    fild%z1\t%1
4461    #"
4462   [(set_attr "type" "fmov,multi")
4463    (set_attr "mode" "SF")
4464    (set_attr "unit" "*,i387")
4465    (set_attr "fp_int_src" "true")])
4467 (define_expand "floatsisf2"
4468   [(set (match_operand:SF 0 "register_operand" "")
4469         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4470   "TARGET_80387 || TARGET_SSE_MATH"
4471   "")
4473 (define_insn "*floatsisf2_mixed"
4474   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4475         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4476   "TARGET_MIX_SSE_I387"
4477   "@
4478    fild%z1\t%1
4479    #
4480    cvtsi2ss\t{%1, %0|%0, %1}
4481    cvtsi2ss\t{%1, %0|%0, %1}"
4482   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4483    (set_attr "mode" "SF")
4484    (set_attr "unit" "*,i387,*,*")
4485    (set_attr "athlon_decode" "*,*,vector,double")
4486    (set_attr "fp_int_src" "true")])
4488 (define_insn "*floatsisf2_sse"
4489   [(set (match_operand:SF 0 "register_operand" "=x,x")
4490         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4491   "TARGET_SSE_MATH"
4492   "cvtsi2ss\t{%1, %0|%0, %1}"
4493   [(set_attr "type" "sseicvt")
4494    (set_attr "mode" "SF")
4495    (set_attr "athlon_decode" "vector,double")
4496    (set_attr "fp_int_src" "true")])
4498 (define_insn "*floatsisf2_i387"
4499   [(set (match_operand:SF 0 "register_operand" "=f,f")
4500         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4501   "TARGET_80387"
4502   "@
4503    fild%z1\t%1
4504    #"
4505   [(set_attr "type" "fmov,multi")
4506    (set_attr "mode" "SF")
4507    (set_attr "unit" "*,i387")
4508    (set_attr "fp_int_src" "true")])
4510 (define_expand "floatdisf2"
4511   [(set (match_operand:SF 0 "register_operand" "")
4512         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4513   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4514   "")
4516 (define_insn "*floatdisf2_mixed"
4517   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4518         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4519   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4520   "@
4521    fild%z1\t%1
4522    #
4523    cvtsi2ss{q}\t{%1, %0|%0, %1}
4524    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4525   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4526    (set_attr "mode" "SF")
4527    (set_attr "unit" "*,i387,*,*")
4528    (set_attr "athlon_decode" "*,*,vector,double")
4529    (set_attr "fp_int_src" "true")])
4531 (define_insn "*floatdisf2_sse"
4532   [(set (match_operand:SF 0 "register_operand" "=x,x")
4533         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4534   "TARGET_64BIT && TARGET_SSE_MATH"
4535   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4536   [(set_attr "type" "sseicvt")
4537    (set_attr "mode" "SF")
4538    (set_attr "athlon_decode" "vector,double")
4539    (set_attr "fp_int_src" "true")])
4541 (define_insn "*floatdisf2_i387"
4542   [(set (match_operand:SF 0 "register_operand" "=f,f")
4543         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4544   "TARGET_80387"
4545   "@
4546    fild%z1\t%1
4547    #"
4548   [(set_attr "type" "fmov,multi")
4549    (set_attr "mode" "SF")
4550    (set_attr "unit" "*,i387")
4551    (set_attr "fp_int_src" "true")])
4553 (define_expand "floathidf2"
4554   [(set (match_operand:DF 0 "register_operand" "")
4555         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4556   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4558   if (TARGET_SSE2 && TARGET_SSE_MATH)
4559     {
4560       emit_insn (gen_floatsidf2 (operands[0],
4561                                  convert_to_mode (SImode, operands[1], 0)));
4562       DONE;
4563     }
4566 (define_insn "*floathidf2_i387"
4567   [(set (match_operand:DF 0 "register_operand" "=f,f")
4568         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4569   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4570   "@
4571    fild%z1\t%1
4572    #"
4573   [(set_attr "type" "fmov,multi")
4574    (set_attr "mode" "DF")
4575    (set_attr "unit" "*,i387")
4576    (set_attr "fp_int_src" "true")])
4578 (define_expand "floatsidf2"
4579   [(set (match_operand:DF 0 "register_operand" "")
4580         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4581   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4582   "")
4584 (define_insn "*floatsidf2_mixed"
4585   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4586         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4587   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4588   "@
4589    fild%z1\t%1
4590    #
4591    cvtsi2sd\t{%1, %0|%0, %1}
4592    cvtsi2sd\t{%1, %0|%0, %1}"
4593   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4594    (set_attr "mode" "DF")
4595    (set_attr "unit" "*,i387,*,*")
4596    (set_attr "athlon_decode" "*,*,double,direct")
4597    (set_attr "fp_int_src" "true")])
4599 (define_insn "*floatsidf2_sse"
4600   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4601         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4602   "TARGET_SSE2 && TARGET_SSE_MATH"
4603   "cvtsi2sd\t{%1, %0|%0, %1}"
4604   [(set_attr "type" "sseicvt")
4605    (set_attr "mode" "DF")
4606    (set_attr "athlon_decode" "double,direct")
4607    (set_attr "fp_int_src" "true")])
4609 (define_insn "*floatsidf2_i387"
4610   [(set (match_operand:DF 0 "register_operand" "=f,f")
4611         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4612   "TARGET_80387"
4613   "@
4614    fild%z1\t%1
4615    #"
4616   [(set_attr "type" "fmov,multi")
4617    (set_attr "mode" "DF")
4618    (set_attr "unit" "*,i387")
4619    (set_attr "fp_int_src" "true")])
4621 (define_expand "floatdidf2"
4622   [(set (match_operand:DF 0 "register_operand" "")
4623         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4624   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4625   "")
4627 (define_insn "*floatdidf2_mixed"
4628   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4629         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4630   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4631   "@
4632    fild%z1\t%1
4633    #
4634    cvtsi2sd{q}\t{%1, %0|%0, %1}
4635    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4636   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4637    (set_attr "mode" "DF")
4638    (set_attr "unit" "*,i387,*,*")
4639    (set_attr "athlon_decode" "*,*,double,direct")
4640    (set_attr "fp_int_src" "true")])
4642 (define_insn "*floatdidf2_sse"
4643   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4644         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4645   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4646   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4647   [(set_attr "type" "sseicvt")
4648    (set_attr "mode" "DF")
4649    (set_attr "athlon_decode" "double,direct")
4650    (set_attr "fp_int_src" "true")])
4652 (define_insn "*floatdidf2_i387"
4653   [(set (match_operand:DF 0 "register_operand" "=f,f")
4654         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4655   "TARGET_80387"
4656   "@
4657    fild%z1\t%1
4658    #"
4659   [(set_attr "type" "fmov,multi")
4660    (set_attr "mode" "DF")
4661    (set_attr "unit" "*,i387")
4662    (set_attr "fp_int_src" "true")])
4664 (define_insn "floathixf2"
4665   [(set (match_operand:XF 0 "register_operand" "=f,f")
4666         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4667   "TARGET_80387"
4668   "@
4669    fild%z1\t%1
4670    #"
4671   [(set_attr "type" "fmov,multi")
4672    (set_attr "mode" "XF")
4673    (set_attr "unit" "*,i387")
4674    (set_attr "fp_int_src" "true")])
4676 (define_insn "floatsixf2"
4677   [(set (match_operand:XF 0 "register_operand" "=f,f")
4678         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4679   "TARGET_80387"
4680   "@
4681    fild%z1\t%1
4682    #"
4683   [(set_attr "type" "fmov,multi")
4684    (set_attr "mode" "XF")
4685    (set_attr "unit" "*,i387")
4686    (set_attr "fp_int_src" "true")])
4688 (define_insn "floatdixf2"
4689   [(set (match_operand:XF 0 "register_operand" "=f,f")
4690         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4691   "TARGET_80387"
4692   "@
4693    fild%z1\t%1
4694    #"
4695   [(set_attr "type" "fmov,multi")
4696    (set_attr "mode" "XF")
4697    (set_attr "unit" "*,i387")
4698    (set_attr "fp_int_src" "true")])
4700 ;; %%% Kill these when reload knows how to do it.
4701 (define_split
4702   [(set (match_operand 0 "fp_register_operand" "")
4703         (float (match_operand 1 "register_operand" "")))]
4704   "reload_completed
4705    && TARGET_80387
4706    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4707   [(const_int 0)]
4709   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4710   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4711   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4712   ix86_free_from_memory (GET_MODE (operands[1]));
4713   DONE;
4716 (define_expand "floatunssisf2"
4717   [(use (match_operand:SF 0 "register_operand" ""))
4718    (use (match_operand:SI 1 "register_operand" ""))]
4719   "!TARGET_64BIT && TARGET_SSE_MATH"
4720   "x86_emit_floatuns (operands); DONE;")
4722 (define_expand "floatunsdisf2"
4723   [(use (match_operand:SF 0 "register_operand" ""))
4724    (use (match_operand:DI 1 "register_operand" ""))]
4725   "TARGET_64BIT && TARGET_SSE_MATH"
4726   "x86_emit_floatuns (operands); DONE;")
4728 (define_expand "floatunsdidf2"
4729   [(use (match_operand:DF 0 "register_operand" ""))
4730    (use (match_operand:DI 1 "register_operand" ""))]
4731   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4732   "x86_emit_floatuns (operands); DONE;")
4734 ;; SSE extract/set expanders
4737 ;; Add instructions
4739 ;; %%% splits for addditi3
4741 (define_expand "addti3"
4742   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4743         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4744                  (match_operand:TI 2 "x86_64_general_operand" "")))
4745    (clobber (reg:CC FLAGS_REG))]
4746   "TARGET_64BIT"
4747   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4749 (define_insn "*addti3_1"
4750   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4751         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4752                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4753    (clobber (reg:CC FLAGS_REG))]
4754   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4755   "#")
4757 (define_split
4758   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4759         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4760                  (match_operand:TI 2 "general_operand" "")))
4761    (clobber (reg:CC FLAGS_REG))]
4762   "TARGET_64BIT && reload_completed"
4763   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4764                                           UNSPEC_ADD_CARRY))
4765               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4766    (parallel [(set (match_dup 3)
4767                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4768                                      (match_dup 4))
4769                             (match_dup 5)))
4770               (clobber (reg:CC FLAGS_REG))])]
4771   "split_ti (operands+0, 1, operands+0, operands+3);
4772    split_ti (operands+1, 1, operands+1, operands+4);
4773    split_ti (operands+2, 1, operands+2, operands+5);")
4775 ;; %%% splits for addsidi3
4776 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4777 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4778 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4780 (define_expand "adddi3"
4781   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4782         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4783                  (match_operand:DI 2 "x86_64_general_operand" "")))
4784    (clobber (reg:CC FLAGS_REG))]
4785   ""
4786   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4788 (define_insn "*adddi3_1"
4789   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4790         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4791                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4792    (clobber (reg:CC FLAGS_REG))]
4793   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4794   "#")
4796 (define_split
4797   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4798         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4799                  (match_operand:DI 2 "general_operand" "")))
4800    (clobber (reg:CC FLAGS_REG))]
4801   "!TARGET_64BIT && reload_completed"
4802   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4803                                           UNSPEC_ADD_CARRY))
4804               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4805    (parallel [(set (match_dup 3)
4806                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4807                                      (match_dup 4))
4808                             (match_dup 5)))
4809               (clobber (reg:CC FLAGS_REG))])]
4810   "split_di (operands+0, 1, operands+0, operands+3);
4811    split_di (operands+1, 1, operands+1, operands+4);
4812    split_di (operands+2, 1, operands+2, operands+5);")
4814 (define_insn "adddi3_carry_rex64"
4815   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4816           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4817                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4818                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4819    (clobber (reg:CC FLAGS_REG))]
4820   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4821   "adc{q}\t{%2, %0|%0, %2}"
4822   [(set_attr "type" "alu")
4823    (set_attr "pent_pair" "pu")
4824    (set_attr "mode" "DI")])
4826 (define_insn "*adddi3_cc_rex64"
4827   [(set (reg:CC FLAGS_REG)
4828         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4829                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4830                    UNSPEC_ADD_CARRY))
4831    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4832         (plus:DI (match_dup 1) (match_dup 2)))]
4833   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834   "add{q}\t{%2, %0|%0, %2}"
4835   [(set_attr "type" "alu")
4836    (set_attr "mode" "DI")])
4838 (define_insn "addqi3_carry"
4839   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4840           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4841                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4842                    (match_operand:QI 2 "general_operand" "qi,qm")))
4843    (clobber (reg:CC FLAGS_REG))]
4844   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4845   "adc{b}\t{%2, %0|%0, %2}"
4846   [(set_attr "type" "alu")
4847    (set_attr "pent_pair" "pu")
4848    (set_attr "mode" "QI")])
4850 (define_insn "addhi3_carry"
4851   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4852           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4853                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4854                    (match_operand:HI 2 "general_operand" "ri,rm")))
4855    (clobber (reg:CC FLAGS_REG))]
4856   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4857   "adc{w}\t{%2, %0|%0, %2}"
4858   [(set_attr "type" "alu")
4859    (set_attr "pent_pair" "pu")
4860    (set_attr "mode" "HI")])
4862 (define_insn "addsi3_carry"
4863   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4865                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4866                    (match_operand:SI 2 "general_operand" "ri,rm")))
4867    (clobber (reg:CC FLAGS_REG))]
4868   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4869   "adc{l}\t{%2, %0|%0, %2}"
4870   [(set_attr "type" "alu")
4871    (set_attr "pent_pair" "pu")
4872    (set_attr "mode" "SI")])
4874 (define_insn "*addsi3_carry_zext"
4875   [(set (match_operand:DI 0 "register_operand" "=r")
4876           (zero_extend:DI 
4877             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4878                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4879                      (match_operand:SI 2 "general_operand" "rim"))))
4880    (clobber (reg:CC FLAGS_REG))]
4881   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4882   "adc{l}\t{%2, %k0|%k0, %2}"
4883   [(set_attr "type" "alu")
4884    (set_attr "pent_pair" "pu")
4885    (set_attr "mode" "SI")])
4887 (define_insn "*addsi3_cc"
4888   [(set (reg:CC FLAGS_REG)
4889         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4890                     (match_operand:SI 2 "general_operand" "ri,rm")]
4891                    UNSPEC_ADD_CARRY))
4892    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4893         (plus:SI (match_dup 1) (match_dup 2)))]
4894   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4895   "add{l}\t{%2, %0|%0, %2}"
4896   [(set_attr "type" "alu")
4897    (set_attr "mode" "SI")])
4899 (define_insn "addqi3_cc"
4900   [(set (reg:CC FLAGS_REG)
4901         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4902                     (match_operand:QI 2 "general_operand" "qi,qm")]
4903                    UNSPEC_ADD_CARRY))
4904    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4905         (plus:QI (match_dup 1) (match_dup 2)))]
4906   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4907   "add{b}\t{%2, %0|%0, %2}"
4908   [(set_attr "type" "alu")
4909    (set_attr "mode" "QI")])
4911 (define_expand "addsi3"
4912   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4913                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4914                             (match_operand:SI 2 "general_operand" "")))
4915               (clobber (reg:CC FLAGS_REG))])]
4916   ""
4917   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4919 (define_insn "*lea_1"
4920   [(set (match_operand:SI 0 "register_operand" "=r")
4921         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4922   "!TARGET_64BIT"
4923   "lea{l}\t{%a1, %0|%0, %a1}"
4924   [(set_attr "type" "lea")
4925    (set_attr "mode" "SI")])
4927 (define_insn "*lea_1_rex64"
4928   [(set (match_operand:SI 0 "register_operand" "=r")
4929         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4930   "TARGET_64BIT"
4931   "lea{l}\t{%a1, %0|%0, %a1}"
4932   [(set_attr "type" "lea")
4933    (set_attr "mode" "SI")])
4935 (define_insn "*lea_1_zext"
4936   [(set (match_operand:DI 0 "register_operand" "=r")
4937         (zero_extend:DI
4938          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4939   "TARGET_64BIT"
4940   "lea{l}\t{%a1, %k0|%k0, %a1}"
4941   [(set_attr "type" "lea")
4942    (set_attr "mode" "SI")])
4944 (define_insn "*lea_2_rex64"
4945   [(set (match_operand:DI 0 "register_operand" "=r")
4946         (match_operand:DI 1 "no_seg_address_operand" "p"))]
4947   "TARGET_64BIT"
4948   "lea{q}\t{%a1, %0|%0, %a1}"
4949   [(set_attr "type" "lea")
4950    (set_attr "mode" "DI")])
4952 ;; The lea patterns for non-Pmodes needs to be matched by several
4953 ;; insns converted to real lea by splitters.
4955 (define_insn_and_split "*lea_general_1"
4956   [(set (match_operand 0 "register_operand" "=r")
4957         (plus (plus (match_operand 1 "index_register_operand" "l")
4958                     (match_operand 2 "register_operand" "r"))
4959               (match_operand 3 "immediate_operand" "i")))]
4960   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4961     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4962    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4963    && GET_MODE (operands[0]) == GET_MODE (operands[1])
4964    && GET_MODE (operands[0]) == GET_MODE (operands[2])
4965    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4966        || GET_MODE (operands[3]) == VOIDmode)"
4967   "#"
4968   "&& reload_completed"
4969   [(const_int 0)]
4971   rtx pat;
4972   operands[0] = gen_lowpart (SImode, operands[0]);
4973   operands[1] = gen_lowpart (Pmode, operands[1]);
4974   operands[2] = gen_lowpart (Pmode, operands[2]);
4975   operands[3] = gen_lowpart (Pmode, operands[3]);
4976   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4977                       operands[3]);
4978   if (Pmode != SImode)
4979     pat = gen_rtx_SUBREG (SImode, pat, 0);
4980   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4981   DONE;
4983   [(set_attr "type" "lea")
4984    (set_attr "mode" "SI")])
4986 (define_insn_and_split "*lea_general_1_zext"
4987   [(set (match_operand:DI 0 "register_operand" "=r")
4988         (zero_extend:DI
4989           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4990                             (match_operand:SI 2 "register_operand" "r"))
4991                    (match_operand:SI 3 "immediate_operand" "i"))))]
4992   "TARGET_64BIT"
4993   "#"
4994   "&& reload_completed"
4995   [(set (match_dup 0)
4996         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4997                                                      (match_dup 2))
4998                                             (match_dup 3)) 0)))]
5000   operands[1] = gen_lowpart (Pmode, operands[1]);
5001   operands[2] = gen_lowpart (Pmode, operands[2]);
5002   operands[3] = gen_lowpart (Pmode, operands[3]);
5004   [(set_attr "type" "lea")
5005    (set_attr "mode" "SI")])
5007 (define_insn_and_split "*lea_general_2"
5008   [(set (match_operand 0 "register_operand" "=r")
5009         (plus (mult (match_operand 1 "index_register_operand" "l")
5010                     (match_operand 2 "const248_operand" "i"))
5011               (match_operand 3 "nonmemory_operand" "ri")))]
5012   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5013     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5014    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5015    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5016    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5017        || GET_MODE (operands[3]) == VOIDmode)"
5018   "#"
5019   "&& reload_completed"
5020   [(const_int 0)]
5022   rtx pat;
5023   operands[0] = gen_lowpart (SImode, operands[0]);
5024   operands[1] = gen_lowpart (Pmode, operands[1]);
5025   operands[3] = gen_lowpart (Pmode, operands[3]);
5026   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5027                       operands[3]);
5028   if (Pmode != SImode)
5029     pat = gen_rtx_SUBREG (SImode, pat, 0);
5030   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5031   DONE;
5033   [(set_attr "type" "lea")
5034    (set_attr "mode" "SI")])
5036 (define_insn_and_split "*lea_general_2_zext"
5037   [(set (match_operand:DI 0 "register_operand" "=r")
5038         (zero_extend:DI
5039           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5040                             (match_operand:SI 2 "const248_operand" "n"))
5041                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5042   "TARGET_64BIT"
5043   "#"
5044   "&& reload_completed"
5045   [(set (match_dup 0)
5046         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5047                                                      (match_dup 2))
5048                                             (match_dup 3)) 0)))]
5050   operands[1] = gen_lowpart (Pmode, operands[1]);
5051   operands[3] = gen_lowpart (Pmode, operands[3]);
5053   [(set_attr "type" "lea")
5054    (set_attr "mode" "SI")])
5056 (define_insn_and_split "*lea_general_3"
5057   [(set (match_operand 0 "register_operand" "=r")
5058         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5059                           (match_operand 2 "const248_operand" "i"))
5060                     (match_operand 3 "register_operand" "r"))
5061               (match_operand 4 "immediate_operand" "i")))]
5062   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5063     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5064    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5065    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5066    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5067   "#"
5068   "&& reload_completed"
5069   [(const_int 0)]
5071   rtx pat;
5072   operands[0] = gen_lowpart (SImode, operands[0]);
5073   operands[1] = gen_lowpart (Pmode, operands[1]);
5074   operands[3] = gen_lowpart (Pmode, operands[3]);
5075   operands[4] = gen_lowpart (Pmode, operands[4]);
5076   pat = gen_rtx_PLUS (Pmode,
5077                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5078                                                          operands[2]),
5079                                     operands[3]),
5080                       operands[4]);
5081   if (Pmode != SImode)
5082     pat = gen_rtx_SUBREG (SImode, pat, 0);
5083   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5084   DONE;
5086   [(set_attr "type" "lea")
5087    (set_attr "mode" "SI")])
5089 (define_insn_and_split "*lea_general_3_zext"
5090   [(set (match_operand:DI 0 "register_operand" "=r")
5091         (zero_extend:DI
5092           (plus:SI (plus:SI (mult:SI
5093                               (match_operand:SI 1 "index_register_operand" "l")
5094                               (match_operand:SI 2 "const248_operand" "n"))
5095                             (match_operand:SI 3 "register_operand" "r"))
5096                    (match_operand:SI 4 "immediate_operand" "i"))))]
5097   "TARGET_64BIT"
5098   "#"
5099   "&& reload_completed"
5100   [(set (match_dup 0)
5101         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5102                                                               (match_dup 2))
5103                                                      (match_dup 3))
5104                                             (match_dup 4)) 0)))]
5106   operands[1] = gen_lowpart (Pmode, operands[1]);
5107   operands[3] = gen_lowpart (Pmode, operands[3]);
5108   operands[4] = gen_lowpart (Pmode, operands[4]);
5110   [(set_attr "type" "lea")
5111    (set_attr "mode" "SI")])
5113 (define_insn "*adddi_1_rex64"
5114   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5115         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5116                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5117    (clobber (reg:CC FLAGS_REG))]
5118   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120   switch (get_attr_type (insn))
5121     {
5122     case TYPE_LEA:
5123       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5124       return "lea{q}\t{%a2, %0|%0, %a2}";
5126     case TYPE_INCDEC:
5127       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5128       if (operands[2] == const1_rtx)
5129         return "inc{q}\t%0";
5130       else
5131         {
5132           gcc_assert (operands[2] == constm1_rtx);
5133           return "dec{q}\t%0";
5134         }
5136     default:
5137       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5139       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5140          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5141       if (GET_CODE (operands[2]) == CONST_INT
5142           /* Avoid overflows.  */
5143           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5144           && (INTVAL (operands[2]) == 128
5145               || (INTVAL (operands[2]) < 0
5146                   && INTVAL (operands[2]) != -128)))
5147         {
5148           operands[2] = GEN_INT (-INTVAL (operands[2]));
5149           return "sub{q}\t{%2, %0|%0, %2}";
5150         }
5151       return "add{q}\t{%2, %0|%0, %2}";
5152     }
5154   [(set (attr "type")
5155      (cond [(eq_attr "alternative" "2")
5156               (const_string "lea")
5157             ; Current assemblers are broken and do not allow @GOTOFF in
5158             ; ought but a memory context.
5159             (match_operand:DI 2 "pic_symbolic_operand" "")
5160               (const_string "lea")
5161             (match_operand:DI 2 "incdec_operand" "")
5162               (const_string "incdec")
5163            ]
5164            (const_string "alu")))
5165    (set_attr "mode" "DI")])
5167 ;; Convert lea to the lea pattern to avoid flags dependency.
5168 (define_split
5169   [(set (match_operand:DI 0 "register_operand" "")
5170         (plus:DI (match_operand:DI 1 "register_operand" "")
5171                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5172    (clobber (reg:CC FLAGS_REG))]
5173   "TARGET_64BIT && reload_completed
5174    && true_regnum (operands[0]) != true_regnum (operands[1])"
5175   [(set (match_dup 0)
5176         (plus:DI (match_dup 1)
5177                  (match_dup 2)))]
5178   "")
5180 (define_insn "*adddi_2_rex64"
5181   [(set (reg FLAGS_REG)
5182         (compare
5183           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5184                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5185           (const_int 0)))                       
5186    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5187         (plus:DI (match_dup 1) (match_dup 2)))]
5188   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5189    && ix86_binary_operator_ok (PLUS, DImode, operands)
5190    /* Current assemblers are broken and do not allow @GOTOFF in
5191       ought but a memory context.  */
5192    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5194   switch (get_attr_type (insn))
5195     {
5196     case TYPE_INCDEC:
5197       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5198       if (operands[2] == const1_rtx)
5199         return "inc{q}\t%0";
5200       else
5201         {
5202           gcc_assert (operands[2] == constm1_rtx);
5203           return "dec{q}\t%0";
5204         }
5206     default:
5207       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5208       /* ???? We ought to handle there the 32bit case too
5209          - do we need new constraint?  */
5210       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5211          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5212       if (GET_CODE (operands[2]) == CONST_INT
5213           /* Avoid overflows.  */
5214           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5215           && (INTVAL (operands[2]) == 128
5216               || (INTVAL (operands[2]) < 0
5217                   && INTVAL (operands[2]) != -128)))
5218         {
5219           operands[2] = GEN_INT (-INTVAL (operands[2]));
5220           return "sub{q}\t{%2, %0|%0, %2}";
5221         }
5222       return "add{q}\t{%2, %0|%0, %2}";
5223     }
5225   [(set (attr "type")
5226      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5227         (const_string "incdec")
5228         (const_string "alu")))
5229    (set_attr "mode" "DI")])
5231 (define_insn "*adddi_3_rex64"
5232   [(set (reg FLAGS_REG)
5233         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5234                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5235    (clobber (match_scratch:DI 0 "=r"))]
5236   "TARGET_64BIT
5237    && ix86_match_ccmode (insn, CCZmode)
5238    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5239    /* Current assemblers are broken and do not allow @GOTOFF in
5240       ought but a memory context.  */
5241    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5243   switch (get_attr_type (insn))
5244     {
5245     case TYPE_INCDEC:
5246       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5247       if (operands[2] == const1_rtx)
5248         return "inc{q}\t%0";
5249       else
5250         {
5251           gcc_assert (operands[2] == constm1_rtx);
5252           return "dec{q}\t%0";
5253         }
5255     default:
5256       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5257       /* ???? We ought to handle there the 32bit case too
5258          - do we need new constraint?  */
5259       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5260          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5261       if (GET_CODE (operands[2]) == CONST_INT
5262           /* Avoid overflows.  */
5263           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5264           && (INTVAL (operands[2]) == 128
5265               || (INTVAL (operands[2]) < 0
5266                   && INTVAL (operands[2]) != -128)))
5267         {
5268           operands[2] = GEN_INT (-INTVAL (operands[2]));
5269           return "sub{q}\t{%2, %0|%0, %2}";
5270         }
5271       return "add{q}\t{%2, %0|%0, %2}";
5272     }
5274   [(set (attr "type")
5275      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5276         (const_string "incdec")
5277         (const_string "alu")))
5278    (set_attr "mode" "DI")])
5280 ; For comparisons against 1, -1 and 128, we may generate better code
5281 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5282 ; is matched then.  We can't accept general immediate, because for
5283 ; case of overflows,  the result is messed up.
5284 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5285 ; when negated.
5286 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5287 ; only for comparisons not depending on it.
5288 (define_insn "*adddi_4_rex64"
5289   [(set (reg FLAGS_REG)
5290         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5291                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5292    (clobber (match_scratch:DI 0 "=rm"))]
5293   "TARGET_64BIT
5294    &&  ix86_match_ccmode (insn, CCGCmode)"
5296   switch (get_attr_type (insn))
5297     {
5298     case TYPE_INCDEC:
5299       if (operands[2] == constm1_rtx)
5300         return "inc{q}\t%0";
5301       else
5302         {
5303           gcc_assert (operands[2] == const1_rtx);
5304           return "dec{q}\t%0";
5305         }
5307     default:
5308       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5309       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5310          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5311       if ((INTVAL (operands[2]) == -128
5312            || (INTVAL (operands[2]) > 0
5313                && INTVAL (operands[2]) != 128))
5314           /* Avoid overflows.  */
5315           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5316         return "sub{q}\t{%2, %0|%0, %2}";
5317       operands[2] = GEN_INT (-INTVAL (operands[2]));
5318       return "add{q}\t{%2, %0|%0, %2}";
5319     }
5321   [(set (attr "type")
5322      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5323         (const_string "incdec")
5324         (const_string "alu")))
5325    (set_attr "mode" "DI")])
5327 (define_insn "*adddi_5_rex64"
5328   [(set (reg FLAGS_REG)
5329         (compare
5330           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5331                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5332           (const_int 0)))                       
5333    (clobber (match_scratch:DI 0 "=r"))]
5334   "TARGET_64BIT
5335    && ix86_match_ccmode (insn, CCGOCmode)
5336    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5337    /* Current assemblers are broken and do not allow @GOTOFF in
5338       ought but a memory context.  */
5339    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5341   switch (get_attr_type (insn))
5342     {
5343     case TYPE_INCDEC:
5344       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5345       if (operands[2] == const1_rtx)
5346         return "inc{q}\t%0";
5347       else
5348         {
5349           gcc_assert (operands[2] == constm1_rtx);
5350           return "dec{q}\t%0";
5351         }
5353     default:
5354       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5355       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5356          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5357       if (GET_CODE (operands[2]) == CONST_INT
5358           /* Avoid overflows.  */
5359           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5360           && (INTVAL (operands[2]) == 128
5361               || (INTVAL (operands[2]) < 0
5362                   && INTVAL (operands[2]) != -128)))
5363         {
5364           operands[2] = GEN_INT (-INTVAL (operands[2]));
5365           return "sub{q}\t{%2, %0|%0, %2}";
5366         }
5367       return "add{q}\t{%2, %0|%0, %2}";
5368     }
5370   [(set (attr "type")
5371      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5372         (const_string "incdec")
5373         (const_string "alu")))
5374    (set_attr "mode" "DI")])
5377 (define_insn "*addsi_1"
5378   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5379         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5380                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5381    (clobber (reg:CC FLAGS_REG))]
5382   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5384   switch (get_attr_type (insn))
5385     {
5386     case TYPE_LEA:
5387       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5388       return "lea{l}\t{%a2, %0|%0, %a2}";
5390     case TYPE_INCDEC:
5391       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5392       if (operands[2] == const1_rtx)
5393         return "inc{l}\t%0";
5394       else
5395         {
5396           gcc_assert (operands[2] == constm1_rtx);
5397           return "dec{l}\t%0";
5398         }
5400     default:
5401       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5403       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5404          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5405       if (GET_CODE (operands[2]) == CONST_INT
5406           && (INTVAL (operands[2]) == 128
5407               || (INTVAL (operands[2]) < 0
5408                   && INTVAL (operands[2]) != -128)))
5409         {
5410           operands[2] = GEN_INT (-INTVAL (operands[2]));
5411           return "sub{l}\t{%2, %0|%0, %2}";
5412         }
5413       return "add{l}\t{%2, %0|%0, %2}";
5414     }
5416   [(set (attr "type")
5417      (cond [(eq_attr "alternative" "2")
5418               (const_string "lea")
5419             ; Current assemblers are broken and do not allow @GOTOFF in
5420             ; ought but a memory context.
5421             (match_operand:SI 2 "pic_symbolic_operand" "")
5422               (const_string "lea")
5423             (match_operand:SI 2 "incdec_operand" "")
5424               (const_string "incdec")
5425            ]
5426            (const_string "alu")))
5427    (set_attr "mode" "SI")])
5429 ;; Convert lea to the lea pattern to avoid flags dependency.
5430 (define_split
5431   [(set (match_operand 0 "register_operand" "")
5432         (plus (match_operand 1 "register_operand" "")
5433               (match_operand 2 "nonmemory_operand" "")))
5434    (clobber (reg:CC FLAGS_REG))]
5435   "reload_completed
5436    && true_regnum (operands[0]) != true_regnum (operands[1])"
5437   [(const_int 0)]
5439   rtx pat;
5440   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5441      may confuse gen_lowpart.  */
5442   if (GET_MODE (operands[0]) != Pmode)
5443     {
5444       operands[1] = gen_lowpart (Pmode, operands[1]);
5445       operands[2] = gen_lowpart (Pmode, operands[2]);
5446     }
5447   operands[0] = gen_lowpart (SImode, operands[0]);
5448   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5449   if (Pmode != SImode)
5450     pat = gen_rtx_SUBREG (SImode, pat, 0);
5451   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5452   DONE;
5455 ;; It may seem that nonimmediate operand is proper one for operand 1.
5456 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5457 ;; we take care in ix86_binary_operator_ok to not allow two memory
5458 ;; operands so proper swapping will be done in reload.  This allow
5459 ;; patterns constructed from addsi_1 to match.
5460 (define_insn "addsi_1_zext"
5461   [(set (match_operand:DI 0 "register_operand" "=r,r")
5462         (zero_extend:DI
5463           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5464                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5465    (clobber (reg:CC FLAGS_REG))]
5466   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5468   switch (get_attr_type (insn))
5469     {
5470     case TYPE_LEA:
5471       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5472       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5474     case TYPE_INCDEC:
5475       if (operands[2] == const1_rtx)
5476         return "inc{l}\t%k0";
5477       else
5478         {
5479           gcc_assert (operands[2] == constm1_rtx);
5480           return "dec{l}\t%k0";
5481         }
5483     default:
5484       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5485          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5486       if (GET_CODE (operands[2]) == CONST_INT
5487           && (INTVAL (operands[2]) == 128
5488               || (INTVAL (operands[2]) < 0
5489                   && INTVAL (operands[2]) != -128)))
5490         {
5491           operands[2] = GEN_INT (-INTVAL (operands[2]));
5492           return "sub{l}\t{%2, %k0|%k0, %2}";
5493         }
5494       return "add{l}\t{%2, %k0|%k0, %2}";
5495     }
5497   [(set (attr "type")
5498      (cond [(eq_attr "alternative" "1")
5499               (const_string "lea")
5500             ; Current assemblers are broken and do not allow @GOTOFF in
5501             ; ought but a memory context.
5502             (match_operand:SI 2 "pic_symbolic_operand" "")
5503               (const_string "lea")
5504             (match_operand:SI 2 "incdec_operand" "")
5505               (const_string "incdec")
5506            ]
5507            (const_string "alu")))
5508    (set_attr "mode" "SI")])
5510 ;; Convert lea to the lea pattern to avoid flags dependency.
5511 (define_split
5512   [(set (match_operand:DI 0 "register_operand" "")
5513         (zero_extend:DI
5514           (plus:SI (match_operand:SI 1 "register_operand" "")
5515                    (match_operand:SI 2 "nonmemory_operand" ""))))
5516    (clobber (reg:CC FLAGS_REG))]
5517   "TARGET_64BIT && reload_completed
5518    && true_regnum (operands[0]) != true_regnum (operands[1])"
5519   [(set (match_dup 0)
5520         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5522   operands[1] = gen_lowpart (Pmode, operands[1]);
5523   operands[2] = gen_lowpart (Pmode, operands[2]);
5526 (define_insn "*addsi_2"
5527   [(set (reg FLAGS_REG)
5528         (compare
5529           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5530                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5531           (const_int 0)))                       
5532    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5533         (plus:SI (match_dup 1) (match_dup 2)))]
5534   "ix86_match_ccmode (insn, CCGOCmode)
5535    && ix86_binary_operator_ok (PLUS, SImode, operands)
5536    /* Current assemblers are broken and do not allow @GOTOFF in
5537       ought but a memory context.  */
5538    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5540   switch (get_attr_type (insn))
5541     {
5542     case TYPE_INCDEC:
5543       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5544       if (operands[2] == const1_rtx)
5545         return "inc{l}\t%0";
5546       else
5547         {
5548           gcc_assert (operands[2] == constm1_rtx);
5549           return "dec{l}\t%0";
5550         }
5552     default:
5553       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5554       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5555          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5556       if (GET_CODE (operands[2]) == CONST_INT
5557           && (INTVAL (operands[2]) == 128
5558               || (INTVAL (operands[2]) < 0
5559                   && INTVAL (operands[2]) != -128)))
5560         {
5561           operands[2] = GEN_INT (-INTVAL (operands[2]));
5562           return "sub{l}\t{%2, %0|%0, %2}";
5563         }
5564       return "add{l}\t{%2, %0|%0, %2}";
5565     }
5567   [(set (attr "type")
5568      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5569         (const_string "incdec")
5570         (const_string "alu")))
5571    (set_attr "mode" "SI")])
5573 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5574 (define_insn "*addsi_2_zext"
5575   [(set (reg FLAGS_REG)
5576         (compare
5577           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5578                    (match_operand:SI 2 "general_operand" "rmni"))
5579           (const_int 0)))                       
5580    (set (match_operand:DI 0 "register_operand" "=r")
5581         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5582   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5583    && ix86_binary_operator_ok (PLUS, SImode, operands)
5584    /* Current assemblers are broken and do not allow @GOTOFF in
5585       ought but a memory context.  */
5586    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5588   switch (get_attr_type (insn))
5589     {
5590     case TYPE_INCDEC:
5591       if (operands[2] == const1_rtx)
5592         return "inc{l}\t%k0";
5593       else
5594         {
5595           gcc_assert (operands[2] == constm1_rtx);
5596           return "dec{l}\t%k0";
5597         }
5599     default:
5600       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5601          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5602       if (GET_CODE (operands[2]) == CONST_INT
5603           && (INTVAL (operands[2]) == 128
5604               || (INTVAL (operands[2]) < 0
5605                   && INTVAL (operands[2]) != -128)))
5606         {
5607           operands[2] = GEN_INT (-INTVAL (operands[2]));
5608           return "sub{l}\t{%2, %k0|%k0, %2}";
5609         }
5610       return "add{l}\t{%2, %k0|%k0, %2}";
5611     }
5613   [(set (attr "type")
5614      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5615         (const_string "incdec")
5616         (const_string "alu")))
5617    (set_attr "mode" "SI")])
5619 (define_insn "*addsi_3"
5620   [(set (reg FLAGS_REG)
5621         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5622                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5623    (clobber (match_scratch:SI 0 "=r"))]
5624   "ix86_match_ccmode (insn, CCZmode)
5625    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5626    /* Current assemblers are broken and do not allow @GOTOFF in
5627       ought but a memory context.  */
5628    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5630   switch (get_attr_type (insn))
5631     {
5632     case TYPE_INCDEC:
5633       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634       if (operands[2] == const1_rtx)
5635         return "inc{l}\t%0";
5636       else
5637         {
5638           gcc_assert (operands[2] == constm1_rtx);
5639           return "dec{l}\t%0";
5640         }
5642     default:
5643       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5645          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5646       if (GET_CODE (operands[2]) == CONST_INT
5647           && (INTVAL (operands[2]) == 128
5648               || (INTVAL (operands[2]) < 0
5649                   && INTVAL (operands[2]) != -128)))
5650         {
5651           operands[2] = GEN_INT (-INTVAL (operands[2]));
5652           return "sub{l}\t{%2, %0|%0, %2}";
5653         }
5654       return "add{l}\t{%2, %0|%0, %2}";
5655     }
5657   [(set (attr "type")
5658      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5659         (const_string "incdec")
5660         (const_string "alu")))
5661    (set_attr "mode" "SI")])
5663 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5664 (define_insn "*addsi_3_zext"
5665   [(set (reg FLAGS_REG)
5666         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5667                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5668    (set (match_operand:DI 0 "register_operand" "=r")
5669         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5670   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5671    && ix86_binary_operator_ok (PLUS, SImode, operands)
5672    /* Current assemblers are broken and do not allow @GOTOFF in
5673       ought but a memory context.  */
5674    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5676   switch (get_attr_type (insn))
5677     {
5678     case TYPE_INCDEC:
5679       if (operands[2] == const1_rtx)
5680         return "inc{l}\t%k0";
5681       else
5682         {
5683           gcc_assert (operands[2] == constm1_rtx);
5684           return "dec{l}\t%k0";
5685         }
5687     default:
5688       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5689          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5690       if (GET_CODE (operands[2]) == CONST_INT
5691           && (INTVAL (operands[2]) == 128
5692               || (INTVAL (operands[2]) < 0
5693                   && INTVAL (operands[2]) != -128)))
5694         {
5695           operands[2] = GEN_INT (-INTVAL (operands[2]));
5696           return "sub{l}\t{%2, %k0|%k0, %2}";
5697         }
5698       return "add{l}\t{%2, %k0|%k0, %2}";
5699     }
5701   [(set (attr "type")
5702      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5703         (const_string "incdec")
5704         (const_string "alu")))
5705    (set_attr "mode" "SI")])
5707 ; For comparisons against 1, -1 and 128, we may generate better code
5708 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5709 ; is matched then.  We can't accept general immediate, because for
5710 ; case of overflows,  the result is messed up.
5711 ; This pattern also don't hold of 0x80000000, since the value overflows
5712 ; when negated.
5713 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5714 ; only for comparisons not depending on it.
5715 (define_insn "*addsi_4"
5716   [(set (reg FLAGS_REG)
5717         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5718                  (match_operand:SI 2 "const_int_operand" "n")))
5719    (clobber (match_scratch:SI 0 "=rm"))]
5720   "ix86_match_ccmode (insn, CCGCmode)
5721    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5723   switch (get_attr_type (insn))
5724     {
5725     case TYPE_INCDEC:
5726       if (operands[2] == constm1_rtx)
5727         return "inc{l}\t%0";
5728       else
5729         {
5730           gcc_assert (operands[2] == const1_rtx);
5731           return "dec{l}\t%0";
5732         }
5734     default:
5735       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5737          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5738       if ((INTVAL (operands[2]) == -128
5739            || (INTVAL (operands[2]) > 0
5740                && INTVAL (operands[2]) != 128)))
5741         return "sub{l}\t{%2, %0|%0, %2}";
5742       operands[2] = GEN_INT (-INTVAL (operands[2]));
5743       return "add{l}\t{%2, %0|%0, %2}";
5744     }
5746   [(set (attr "type")
5747      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5748         (const_string "incdec")
5749         (const_string "alu")))
5750    (set_attr "mode" "SI")])
5752 (define_insn "*addsi_5"
5753   [(set (reg FLAGS_REG)
5754         (compare
5755           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5756                    (match_operand:SI 2 "general_operand" "rmni"))
5757           (const_int 0)))                       
5758    (clobber (match_scratch:SI 0 "=r"))]
5759   "ix86_match_ccmode (insn, CCGOCmode)
5760    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5761    /* Current assemblers are broken and do not allow @GOTOFF in
5762       ought but a memory context.  */
5763    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5765   switch (get_attr_type (insn))
5766     {
5767     case TYPE_INCDEC:
5768       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5769       if (operands[2] == const1_rtx)
5770         return "inc{l}\t%0";
5771       else
5772         {
5773           gcc_assert (operands[2] == constm1_rtx);
5774           return "dec{l}\t%0";
5775         }
5777     default:
5778       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5779       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5780          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5781       if (GET_CODE (operands[2]) == CONST_INT
5782           && (INTVAL (operands[2]) == 128
5783               || (INTVAL (operands[2]) < 0
5784                   && INTVAL (operands[2]) != -128)))
5785         {
5786           operands[2] = GEN_INT (-INTVAL (operands[2]));
5787           return "sub{l}\t{%2, %0|%0, %2}";
5788         }
5789       return "add{l}\t{%2, %0|%0, %2}";
5790     }
5792   [(set (attr "type")
5793      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5794         (const_string "incdec")
5795         (const_string "alu")))
5796    (set_attr "mode" "SI")])
5798 (define_expand "addhi3"
5799   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5800                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5801                             (match_operand:HI 2 "general_operand" "")))
5802               (clobber (reg:CC FLAGS_REG))])]
5803   "TARGET_HIMODE_MATH"
5804   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5806 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5807 ;; type optimizations enabled by define-splits.  This is not important
5808 ;; for PII, and in fact harmful because of partial register stalls.
5810 (define_insn "*addhi_1_lea"
5811   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5812         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5813                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5814    (clobber (reg:CC FLAGS_REG))]
5815   "!TARGET_PARTIAL_REG_STALL
5816    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5818   switch (get_attr_type (insn))
5819     {
5820     case TYPE_LEA:
5821       return "#";
5822     case TYPE_INCDEC:
5823       if (operands[2] == const1_rtx)
5824         return "inc{w}\t%0";
5825       else
5826         {
5827           gcc_assert (operands[2] == constm1_rtx);
5828           return "dec{w}\t%0";
5829         }
5831     default:
5832       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5833          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5834       if (GET_CODE (operands[2]) == CONST_INT
5835           && (INTVAL (operands[2]) == 128
5836               || (INTVAL (operands[2]) < 0
5837                   && INTVAL (operands[2]) != -128)))
5838         {
5839           operands[2] = GEN_INT (-INTVAL (operands[2]));
5840           return "sub{w}\t{%2, %0|%0, %2}";
5841         }
5842       return "add{w}\t{%2, %0|%0, %2}";
5843     }
5845   [(set (attr "type")
5846      (if_then_else (eq_attr "alternative" "2")
5847         (const_string "lea")
5848         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5849            (const_string "incdec")
5850            (const_string "alu"))))
5851    (set_attr "mode" "HI,HI,SI")])
5853 (define_insn "*addhi_1"
5854   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5855         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5856                  (match_operand:HI 2 "general_operand" "ri,rm")))
5857    (clobber (reg:CC FLAGS_REG))]
5858   "TARGET_PARTIAL_REG_STALL
5859    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5861   switch (get_attr_type (insn))
5862     {
5863     case TYPE_INCDEC:
5864       if (operands[2] == const1_rtx)
5865         return "inc{w}\t%0";
5866       else
5867         {
5868           gcc_assert (operands[2] == constm1_rtx);
5869           return "dec{w}\t%0";
5870         }
5872     default:
5873       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5875       if (GET_CODE (operands[2]) == CONST_INT
5876           && (INTVAL (operands[2]) == 128
5877               || (INTVAL (operands[2]) < 0
5878                   && INTVAL (operands[2]) != -128)))
5879         {
5880           operands[2] = GEN_INT (-INTVAL (operands[2]));
5881           return "sub{w}\t{%2, %0|%0, %2}";
5882         }
5883       return "add{w}\t{%2, %0|%0, %2}";
5884     }
5886   [(set (attr "type")
5887      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5888         (const_string "incdec")
5889         (const_string "alu")))
5890    (set_attr "mode" "HI")])
5892 (define_insn "*addhi_2"
5893   [(set (reg FLAGS_REG)
5894         (compare
5895           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5897           (const_int 0)))                       
5898    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5899         (plus:HI (match_dup 1) (match_dup 2)))]
5900   "ix86_match_ccmode (insn, CCGOCmode)
5901    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5903   switch (get_attr_type (insn))
5904     {
5905     case TYPE_INCDEC:
5906       if (operands[2] == const1_rtx)
5907         return "inc{w}\t%0";
5908       else
5909         {
5910           gcc_assert (operands[2] == constm1_rtx);
5911           return "dec{w}\t%0";
5912         }
5914     default:
5915       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5917       if (GET_CODE (operands[2]) == CONST_INT
5918           && (INTVAL (operands[2]) == 128
5919               || (INTVAL (operands[2]) < 0
5920                   && INTVAL (operands[2]) != -128)))
5921         {
5922           operands[2] = GEN_INT (-INTVAL (operands[2]));
5923           return "sub{w}\t{%2, %0|%0, %2}";
5924         }
5925       return "add{w}\t{%2, %0|%0, %2}";
5926     }
5928   [(set (attr "type")
5929      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5930         (const_string "incdec")
5931         (const_string "alu")))
5932    (set_attr "mode" "HI")])
5934 (define_insn "*addhi_3"
5935   [(set (reg FLAGS_REG)
5936         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5937                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5938    (clobber (match_scratch:HI 0 "=r"))]
5939   "ix86_match_ccmode (insn, CCZmode)
5940    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5942   switch (get_attr_type (insn))
5943     {
5944     case TYPE_INCDEC:
5945       if (operands[2] == const1_rtx)
5946         return "inc{w}\t%0";
5947       else
5948         {
5949           gcc_assert (operands[2] == constm1_rtx);
5950           return "dec{w}\t%0";
5951         }
5953     default:
5954       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5955          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5956       if (GET_CODE (operands[2]) == CONST_INT
5957           && (INTVAL (operands[2]) == 128
5958               || (INTVAL (operands[2]) < 0
5959                   && INTVAL (operands[2]) != -128)))
5960         {
5961           operands[2] = GEN_INT (-INTVAL (operands[2]));
5962           return "sub{w}\t{%2, %0|%0, %2}";
5963         }
5964       return "add{w}\t{%2, %0|%0, %2}";
5965     }
5967   [(set (attr "type")
5968      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5969         (const_string "incdec")
5970         (const_string "alu")))
5971    (set_attr "mode" "HI")])
5973 ; See comments above addsi_4 for details.
5974 (define_insn "*addhi_4"
5975   [(set (reg FLAGS_REG)
5976         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5977                  (match_operand:HI 2 "const_int_operand" "n")))
5978    (clobber (match_scratch:HI 0 "=rm"))]
5979   "ix86_match_ccmode (insn, CCGCmode)
5980    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5982   switch (get_attr_type (insn))
5983     {
5984     case TYPE_INCDEC:
5985       if (operands[2] == constm1_rtx)
5986         return "inc{w}\t%0";
5987       else
5988         {
5989           gcc_assert (operands[2] == const1_rtx);
5990           return "dec{w}\t%0";
5991         }
5993     default:
5994       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5995       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5997       if ((INTVAL (operands[2]) == -128
5998            || (INTVAL (operands[2]) > 0
5999                && INTVAL (operands[2]) != 128)))
6000         return "sub{w}\t{%2, %0|%0, %2}";
6001       operands[2] = GEN_INT (-INTVAL (operands[2]));
6002       return "add{w}\t{%2, %0|%0, %2}";
6003     }
6005   [(set (attr "type")
6006      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6007         (const_string "incdec")
6008         (const_string "alu")))
6009    (set_attr "mode" "SI")])
6012 (define_insn "*addhi_5"
6013   [(set (reg FLAGS_REG)
6014         (compare
6015           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6016                    (match_operand:HI 2 "general_operand" "rmni"))
6017           (const_int 0)))                       
6018    (clobber (match_scratch:HI 0 "=r"))]
6019   "ix86_match_ccmode (insn, CCGOCmode)
6020    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6022   switch (get_attr_type (insn))
6023     {
6024     case TYPE_INCDEC:
6025       if (operands[2] == const1_rtx)
6026         return "inc{w}\t%0";
6027       else
6028         {
6029           gcc_assert (operands[2] == constm1_rtx);
6030           return "dec{w}\t%0";
6031         }
6033     default:
6034       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6035          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6036       if (GET_CODE (operands[2]) == CONST_INT
6037           && (INTVAL (operands[2]) == 128
6038               || (INTVAL (operands[2]) < 0
6039                   && INTVAL (operands[2]) != -128)))
6040         {
6041           operands[2] = GEN_INT (-INTVAL (operands[2]));
6042           return "sub{w}\t{%2, %0|%0, %2}";
6043         }
6044       return "add{w}\t{%2, %0|%0, %2}";
6045     }
6047   [(set (attr "type")
6048      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6049         (const_string "incdec")
6050         (const_string "alu")))
6051    (set_attr "mode" "HI")])
6053 (define_expand "addqi3"
6054   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6055                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6056                             (match_operand:QI 2 "general_operand" "")))
6057               (clobber (reg:CC FLAGS_REG))])]
6058   "TARGET_QIMODE_MATH"
6059   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6061 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6062 (define_insn "*addqi_1_lea"
6063   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6064         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6065                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6066    (clobber (reg:CC FLAGS_REG))]
6067   "!TARGET_PARTIAL_REG_STALL
6068    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6070   int widen = (which_alternative == 2);
6071   switch (get_attr_type (insn))
6072     {
6073     case TYPE_LEA:
6074       return "#";
6075     case TYPE_INCDEC:
6076       if (operands[2] == const1_rtx)
6077         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6078       else
6079         {
6080           gcc_assert (operands[2] == constm1_rtx);
6081           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6082         }
6084     default:
6085       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6087       if (GET_CODE (operands[2]) == CONST_INT
6088           && (INTVAL (operands[2]) == 128
6089               || (INTVAL (operands[2]) < 0
6090                   && INTVAL (operands[2]) != -128)))
6091         {
6092           operands[2] = GEN_INT (-INTVAL (operands[2]));
6093           if (widen)
6094             return "sub{l}\t{%2, %k0|%k0, %2}";
6095           else
6096             return "sub{b}\t{%2, %0|%0, %2}";
6097         }
6098       if (widen)
6099         return "add{l}\t{%k2, %k0|%k0, %k2}";
6100       else
6101         return "add{b}\t{%2, %0|%0, %2}";
6102     }
6104   [(set (attr "type")
6105      (if_then_else (eq_attr "alternative" "3")
6106         (const_string "lea")
6107         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6108            (const_string "incdec")
6109            (const_string "alu"))))
6110    (set_attr "mode" "QI,QI,SI,SI")])
6112 (define_insn "*addqi_1"
6113   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6114         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6115                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6116    (clobber (reg:CC FLAGS_REG))]
6117   "TARGET_PARTIAL_REG_STALL
6118    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6120   int widen = (which_alternative == 2);
6121   switch (get_attr_type (insn))
6122     {
6123     case TYPE_INCDEC:
6124       if (operands[2] == const1_rtx)
6125         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6126       else
6127         {
6128           gcc_assert (operands[2] == constm1_rtx);
6129           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6130         }
6132     default:
6133       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6134          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6135       if (GET_CODE (operands[2]) == CONST_INT
6136           && (INTVAL (operands[2]) == 128
6137               || (INTVAL (operands[2]) < 0
6138                   && INTVAL (operands[2]) != -128)))
6139         {
6140           operands[2] = GEN_INT (-INTVAL (operands[2]));
6141           if (widen)
6142             return "sub{l}\t{%2, %k0|%k0, %2}";
6143           else
6144             return "sub{b}\t{%2, %0|%0, %2}";
6145         }
6146       if (widen)
6147         return "add{l}\t{%k2, %k0|%k0, %k2}";
6148       else
6149         return "add{b}\t{%2, %0|%0, %2}";
6150     }
6152   [(set (attr "type")
6153      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6154         (const_string "incdec")
6155         (const_string "alu")))
6156    (set_attr "mode" "QI,QI,SI")])
6158 (define_insn "*addqi_1_slp"
6159   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6160         (plus:QI (match_dup 0)
6161                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6162    (clobber (reg:CC FLAGS_REG))]
6163   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6164    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6166   switch (get_attr_type (insn))
6167     {
6168     case TYPE_INCDEC:
6169       if (operands[1] == const1_rtx)
6170         return "inc{b}\t%0";
6171       else
6172         {
6173           gcc_assert (operands[1] == constm1_rtx);
6174           return "dec{b}\t%0";
6175         }
6177     default:
6178       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6179       if (GET_CODE (operands[1]) == CONST_INT
6180           && INTVAL (operands[1]) < 0)
6181         {
6182           operands[1] = GEN_INT (-INTVAL (operands[1]));
6183           return "sub{b}\t{%1, %0|%0, %1}";
6184         }
6185       return "add{b}\t{%1, %0|%0, %1}";
6186     }
6188   [(set (attr "type")
6189      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6190         (const_string "incdec")
6191         (const_string "alu1")))
6192    (set (attr "memory")
6193      (if_then_else (match_operand 1 "memory_operand" "")
6194         (const_string "load")
6195         (const_string "none")))
6196    (set_attr "mode" "QI")])
6198 (define_insn "*addqi_2"
6199   [(set (reg FLAGS_REG)
6200         (compare
6201           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6202                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6203           (const_int 0)))
6204    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6205         (plus:QI (match_dup 1) (match_dup 2)))]
6206   "ix86_match_ccmode (insn, CCGOCmode)
6207    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6209   switch (get_attr_type (insn))
6210     {
6211     case TYPE_INCDEC:
6212       if (operands[2] == const1_rtx)
6213         return "inc{b}\t%0";
6214       else
6215         {
6216           gcc_assert (operands[2] == constm1_rtx
6217                       || (GET_CODE (operands[2]) == CONST_INT
6218                           && INTVAL (operands[2]) == 255));
6219           return "dec{b}\t%0";
6220         }
6222     default:
6223       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6224       if (GET_CODE (operands[2]) == CONST_INT
6225           && INTVAL (operands[2]) < 0)
6226         {
6227           operands[2] = GEN_INT (-INTVAL (operands[2]));
6228           return "sub{b}\t{%2, %0|%0, %2}";
6229         }
6230       return "add{b}\t{%2, %0|%0, %2}";
6231     }
6233   [(set (attr "type")
6234      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6235         (const_string "incdec")
6236         (const_string "alu")))
6237    (set_attr "mode" "QI")])
6239 (define_insn "*addqi_3"
6240   [(set (reg FLAGS_REG)
6241         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6242                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6243    (clobber (match_scratch:QI 0 "=q"))]
6244   "ix86_match_ccmode (insn, CCZmode)
6245    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6247   switch (get_attr_type (insn))
6248     {
6249     case TYPE_INCDEC:
6250       if (operands[2] == const1_rtx)
6251         return "inc{b}\t%0";
6252       else
6253         {
6254           gcc_assert (operands[2] == constm1_rtx
6255                       || (GET_CODE (operands[2]) == CONST_INT
6256                           && INTVAL (operands[2]) == 255));
6257           return "dec{b}\t%0";
6258         }
6260     default:
6261       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6262       if (GET_CODE (operands[2]) == CONST_INT
6263           && INTVAL (operands[2]) < 0)
6264         {
6265           operands[2] = GEN_INT (-INTVAL (operands[2]));
6266           return "sub{b}\t{%2, %0|%0, %2}";
6267         }
6268       return "add{b}\t{%2, %0|%0, %2}";
6269     }
6271   [(set (attr "type")
6272      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6273         (const_string "incdec")
6274         (const_string "alu")))
6275    (set_attr "mode" "QI")])
6277 ; See comments above addsi_4 for details.
6278 (define_insn "*addqi_4"
6279   [(set (reg FLAGS_REG)
6280         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6281                  (match_operand:QI 2 "const_int_operand" "n")))
6282    (clobber (match_scratch:QI 0 "=qm"))]
6283   "ix86_match_ccmode (insn, CCGCmode)
6284    && (INTVAL (operands[2]) & 0xff) != 0x80"
6286   switch (get_attr_type (insn))
6287     {
6288     case TYPE_INCDEC:
6289       if (operands[2] == constm1_rtx
6290           || (GET_CODE (operands[2]) == CONST_INT
6291               && INTVAL (operands[2]) == 255))
6292         return "inc{b}\t%0";
6293       else
6294         {
6295           gcc_assert (operands[2] == const1_rtx);
6296           return "dec{b}\t%0";
6297         }
6299     default:
6300       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6301       if (INTVAL (operands[2]) < 0)
6302         {
6303           operands[2] = GEN_INT (-INTVAL (operands[2]));
6304           return "add{b}\t{%2, %0|%0, %2}";
6305         }
6306       return "sub{b}\t{%2, %0|%0, %2}";
6307     }
6309   [(set (attr "type")
6310      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6311         (const_string "incdec")
6312         (const_string "alu")))
6313    (set_attr "mode" "QI")])
6316 (define_insn "*addqi_5"
6317   [(set (reg FLAGS_REG)
6318         (compare
6319           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6320                    (match_operand:QI 2 "general_operand" "qmni"))
6321           (const_int 0)))
6322    (clobber (match_scratch:QI 0 "=q"))]
6323   "ix86_match_ccmode (insn, CCGOCmode)
6324    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6326   switch (get_attr_type (insn))
6327     {
6328     case TYPE_INCDEC:
6329       if (operands[2] == const1_rtx)
6330         return "inc{b}\t%0";
6331       else
6332         {
6333           gcc_assert (operands[2] == constm1_rtx
6334                       || (GET_CODE (operands[2]) == CONST_INT
6335                           && INTVAL (operands[2]) == 255));
6336           return "dec{b}\t%0";
6337         }
6339     default:
6340       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6341       if (GET_CODE (operands[2]) == CONST_INT
6342           && INTVAL (operands[2]) < 0)
6343         {
6344           operands[2] = GEN_INT (-INTVAL (operands[2]));
6345           return "sub{b}\t{%2, %0|%0, %2}";
6346         }
6347       return "add{b}\t{%2, %0|%0, %2}";
6348     }
6350   [(set (attr "type")
6351      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352         (const_string "incdec")
6353         (const_string "alu")))
6354    (set_attr "mode" "QI")])
6357 (define_insn "addqi_ext_1"
6358   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6359                          (const_int 8)
6360                          (const_int 8))
6361         (plus:SI
6362           (zero_extract:SI
6363             (match_operand 1 "ext_register_operand" "0")
6364             (const_int 8)
6365             (const_int 8))
6366           (match_operand:QI 2 "general_operand" "Qmn")))
6367    (clobber (reg:CC FLAGS_REG))]
6368   "!TARGET_64BIT"
6370   switch (get_attr_type (insn))
6371     {
6372     case TYPE_INCDEC:
6373       if (operands[2] == const1_rtx)
6374         return "inc{b}\t%h0";
6375       else
6376         {
6377           gcc_assert (operands[2] == constm1_rtx
6378                       || (GET_CODE (operands[2]) == CONST_INT
6379                           && INTVAL (operands[2]) == 255));
6380           return "dec{b}\t%h0";
6381         }
6383     default:
6384       return "add{b}\t{%2, %h0|%h0, %2}";
6385     }
6387   [(set (attr "type")
6388      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389         (const_string "incdec")
6390         (const_string "alu")))
6391    (set_attr "mode" "QI")])
6393 (define_insn "*addqi_ext_1_rex64"
6394   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6395                          (const_int 8)
6396                          (const_int 8))
6397         (plus:SI
6398           (zero_extract:SI
6399             (match_operand 1 "ext_register_operand" "0")
6400             (const_int 8)
6401             (const_int 8))
6402           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6403    (clobber (reg:CC FLAGS_REG))]
6404   "TARGET_64BIT"
6406   switch (get_attr_type (insn))
6407     {
6408     case TYPE_INCDEC:
6409       if (operands[2] == const1_rtx)
6410         return "inc{b}\t%h0";
6411       else
6412         {
6413           gcc_assert (operands[2] == constm1_rtx
6414                       || (GET_CODE (operands[2]) == CONST_INT
6415                           && INTVAL (operands[2]) == 255));
6416           return "dec{b}\t%h0";
6417         }
6419     default:
6420       return "add{b}\t{%2, %h0|%h0, %2}";
6421     }
6423   [(set (attr "type")
6424      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6425         (const_string "incdec")
6426         (const_string "alu")))
6427    (set_attr "mode" "QI")])
6429 (define_insn "*addqi_ext_2"
6430   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6431                          (const_int 8)
6432                          (const_int 8))
6433         (plus:SI
6434           (zero_extract:SI
6435             (match_operand 1 "ext_register_operand" "%0")
6436             (const_int 8)
6437             (const_int 8))
6438           (zero_extract:SI
6439             (match_operand 2 "ext_register_operand" "Q")
6440             (const_int 8)
6441             (const_int 8))))
6442    (clobber (reg:CC FLAGS_REG))]
6443   ""
6444   "add{b}\t{%h2, %h0|%h0, %h2}"
6445   [(set_attr "type" "alu")
6446    (set_attr "mode" "QI")])
6448 ;; The patterns that match these are at the end of this file.
6450 (define_expand "addxf3"
6451   [(set (match_operand:XF 0 "register_operand" "")
6452         (plus:XF (match_operand:XF 1 "register_operand" "")
6453                  (match_operand:XF 2 "register_operand" "")))]
6454   "TARGET_80387"
6455   "")
6457 (define_expand "adddf3"
6458   [(set (match_operand:DF 0 "register_operand" "")
6459         (plus:DF (match_operand:DF 1 "register_operand" "")
6460                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6461   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6462   "")
6464 (define_expand "addsf3"
6465   [(set (match_operand:SF 0 "register_operand" "")
6466         (plus:SF (match_operand:SF 1 "register_operand" "")
6467                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6468   "TARGET_80387 || TARGET_SSE_MATH"
6469   "")
6471 ;; Subtract instructions
6473 ;; %%% splits for subditi3
6475 (define_expand "subti3"
6476   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6477                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6478                              (match_operand:TI 2 "x86_64_general_operand" "")))
6479               (clobber (reg:CC FLAGS_REG))])]
6480   "TARGET_64BIT"
6481   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6483 (define_insn "*subti3_1"
6484   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6485         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6486                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6487    (clobber (reg:CC FLAGS_REG))]
6488   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6489   "#")
6491 (define_split
6492   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6493         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6494                   (match_operand:TI 2 "general_operand" "")))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "TARGET_64BIT && reload_completed"
6497   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6498               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6499    (parallel [(set (match_dup 3)
6500                    (minus:DI (match_dup 4)
6501                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6502                                       (match_dup 5))))
6503               (clobber (reg:CC FLAGS_REG))])]
6504   "split_ti (operands+0, 1, operands+0, operands+3);
6505    split_ti (operands+1, 1, operands+1, operands+4);
6506    split_ti (operands+2, 1, operands+2, operands+5);")
6508 ;; %%% splits for subsidi3
6510 (define_expand "subdi3"
6511   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6512                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6513                              (match_operand:DI 2 "x86_64_general_operand" "")))
6514               (clobber (reg:CC FLAGS_REG))])]
6515   ""
6516   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6518 (define_insn "*subdi3_1"
6519   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6520         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6521                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6522    (clobber (reg:CC FLAGS_REG))]
6523   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6524   "#")
6526 (define_split
6527   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6528         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6529                   (match_operand:DI 2 "general_operand" "")))
6530    (clobber (reg:CC FLAGS_REG))]
6531   "!TARGET_64BIT && reload_completed"
6532   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6533               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6534    (parallel [(set (match_dup 3)
6535                    (minus:SI (match_dup 4)
6536                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6537                                       (match_dup 5))))
6538               (clobber (reg:CC FLAGS_REG))])]
6539   "split_di (operands+0, 1, operands+0, operands+3);
6540    split_di (operands+1, 1, operands+1, operands+4);
6541    split_di (operands+2, 1, operands+2, operands+5);")
6543 (define_insn "subdi3_carry_rex64"
6544   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6545           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6546             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6547                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6548    (clobber (reg:CC FLAGS_REG))]
6549   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6550   "sbb{q}\t{%2, %0|%0, %2}"
6551   [(set_attr "type" "alu")
6552    (set_attr "pent_pair" "pu")
6553    (set_attr "mode" "DI")])
6555 (define_insn "*subdi_1_rex64"
6556   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6557         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6559    (clobber (reg:CC FLAGS_REG))]
6560   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6561   "sub{q}\t{%2, %0|%0, %2}"
6562   [(set_attr "type" "alu")
6563    (set_attr "mode" "DI")])
6565 (define_insn "*subdi_2_rex64"
6566   [(set (reg FLAGS_REG)
6567         (compare
6568           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6569                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6570           (const_int 0)))
6571    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6572         (minus:DI (match_dup 1) (match_dup 2)))]
6573   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6574    && 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_3_rex63"
6580   [(set (reg FLAGS_REG)
6581         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6582                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6583    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6584         (minus:DI (match_dup 1) (match_dup 2)))]
6585   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6586    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587   "sub{q}\t{%2, %0|%0, %2}"
6588   [(set_attr "type" "alu")
6589    (set_attr "mode" "DI")])
6591 (define_insn "subqi3_carry"
6592   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6593           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6594             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6595                (match_operand:QI 2 "general_operand" "qi,qm"))))
6596    (clobber (reg:CC FLAGS_REG))]
6597   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6598   "sbb{b}\t{%2, %0|%0, %2}"
6599   [(set_attr "type" "alu")
6600    (set_attr "pent_pair" "pu")
6601    (set_attr "mode" "QI")])
6603 (define_insn "subhi3_carry"
6604   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6605           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6606             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6607                (match_operand:HI 2 "general_operand" "ri,rm"))))
6608    (clobber (reg:CC FLAGS_REG))]
6609   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6610   "sbb{w}\t{%2, %0|%0, %2}"
6611   [(set_attr "type" "alu")
6612    (set_attr "pent_pair" "pu")
6613    (set_attr "mode" "HI")])
6615 (define_insn "subsi3_carry"
6616   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6619                (match_operand:SI 2 "general_operand" "ri,rm"))))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6622   "sbb{l}\t{%2, %0|%0, %2}"
6623   [(set_attr "type" "alu")
6624    (set_attr "pent_pair" "pu")
6625    (set_attr "mode" "SI")])
6627 (define_insn "subsi3_carry_zext"
6628   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6629           (zero_extend:DI
6630             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6631               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6632                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6633    (clobber (reg:CC FLAGS_REG))]
6634   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6635   "sbb{l}\t{%2, %k0|%k0, %2}"
6636   [(set_attr "type" "alu")
6637    (set_attr "pent_pair" "pu")
6638    (set_attr "mode" "SI")])
6640 (define_expand "subsi3"
6641   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6642                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6643                              (match_operand:SI 2 "general_operand" "")))
6644               (clobber (reg:CC FLAGS_REG))])]
6645   ""
6646   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6648 (define_insn "*subsi_1"
6649   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6650         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6651                   (match_operand:SI 2 "general_operand" "ri,rm")))
6652    (clobber (reg:CC FLAGS_REG))]
6653   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6654   "sub{l}\t{%2, %0|%0, %2}"
6655   [(set_attr "type" "alu")
6656    (set_attr "mode" "SI")])
6658 (define_insn "*subsi_1_zext"
6659   [(set (match_operand:DI 0 "register_operand" "=r")
6660         (zero_extend:DI
6661           (minus:SI (match_operand:SI 1 "register_operand" "0")
6662                     (match_operand:SI 2 "general_operand" "rim"))))
6663    (clobber (reg:CC FLAGS_REG))]
6664   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665   "sub{l}\t{%2, %k0|%k0, %2}"
6666   [(set_attr "type" "alu")
6667    (set_attr "mode" "SI")])
6669 (define_insn "*subsi_2"
6670   [(set (reg FLAGS_REG)
6671         (compare
6672           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673                     (match_operand:SI 2 "general_operand" "ri,rm"))
6674           (const_int 0)))
6675    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6676         (minus:SI (match_dup 1) (match_dup 2)))]
6677   "ix86_match_ccmode (insn, CCGOCmode)
6678    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6679   "sub{l}\t{%2, %0|%0, %2}"
6680   [(set_attr "type" "alu")
6681    (set_attr "mode" "SI")])
6683 (define_insn "*subsi_2_zext"
6684   [(set (reg FLAGS_REG)
6685         (compare
6686           (minus:SI (match_operand:SI 1 "register_operand" "0")
6687                     (match_operand:SI 2 "general_operand" "rim"))
6688           (const_int 0)))
6689    (set (match_operand:DI 0 "register_operand" "=r")
6690         (zero_extend:DI
6691           (minus:SI (match_dup 1)
6692                     (match_dup 2))))]
6693   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6694    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6695   "sub{l}\t{%2, %k0|%k0, %2}"
6696   [(set_attr "type" "alu")
6697    (set_attr "mode" "SI")])
6699 (define_insn "*subsi_3"
6700   [(set (reg FLAGS_REG)
6701         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6702                  (match_operand:SI 2 "general_operand" "ri,rm")))
6703    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6704         (minus:SI (match_dup 1) (match_dup 2)))]
6705   "ix86_match_ccmode (insn, CCmode)
6706    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707   "sub{l}\t{%2, %0|%0, %2}"
6708   [(set_attr "type" "alu")
6709    (set_attr "mode" "SI")])
6711 (define_insn "*subsi_3_zext"
6712   [(set (reg FLAGS_REG)
6713         (compare (match_operand:SI 1 "register_operand" "0")
6714                  (match_operand:SI 2 "general_operand" "rim")))
6715    (set (match_operand:DI 0 "register_operand" "=r")
6716         (zero_extend:DI
6717           (minus:SI (match_dup 1)
6718                     (match_dup 2))))]
6719   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6720    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721   "sub{q}\t{%2, %0|%0, %2}"
6722   [(set_attr "type" "alu")
6723    (set_attr "mode" "DI")])
6725 (define_expand "subhi3"
6726   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6727                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6728                              (match_operand:HI 2 "general_operand" "")))
6729               (clobber (reg:CC FLAGS_REG))])]
6730   "TARGET_HIMODE_MATH"
6731   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6733 (define_insn "*subhi_1"
6734   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6735         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6736                   (match_operand:HI 2 "general_operand" "ri,rm")))
6737    (clobber (reg:CC FLAGS_REG))]
6738   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6739   "sub{w}\t{%2, %0|%0, %2}"
6740   [(set_attr "type" "alu")
6741    (set_attr "mode" "HI")])
6743 (define_insn "*subhi_2"
6744   [(set (reg FLAGS_REG)
6745         (compare
6746           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6747                     (match_operand:HI 2 "general_operand" "ri,rm"))
6748           (const_int 0)))
6749    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6750         (minus:HI (match_dup 1) (match_dup 2)))]
6751   "ix86_match_ccmode (insn, CCGOCmode)
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_3"
6758   [(set (reg FLAGS_REG)
6759         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6760                  (match_operand:HI 2 "general_operand" "ri,rm")))
6761    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6762         (minus:HI (match_dup 1) (match_dup 2)))]
6763   "ix86_match_ccmode (insn, CCmode)
6764    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6765   "sub{w}\t{%2, %0|%0, %2}"
6766   [(set_attr "type" "alu")
6767    (set_attr "mode" "HI")])
6769 (define_expand "subqi3"
6770   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6771                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6772                              (match_operand:QI 2 "general_operand" "")))
6773               (clobber (reg:CC FLAGS_REG))])]
6774   "TARGET_QIMODE_MATH"
6775   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6777 (define_insn "*subqi_1"
6778   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6779         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6780                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6781    (clobber (reg:CC FLAGS_REG))]
6782   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6783   "sub{b}\t{%2, %0|%0, %2}"
6784   [(set_attr "type" "alu")
6785    (set_attr "mode" "QI")])
6787 (define_insn "*subqi_1_slp"
6788   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6789         (minus:QI (match_dup 0)
6790                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6791    (clobber (reg:CC FLAGS_REG))]
6792   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6793    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6794   "sub{b}\t{%1, %0|%0, %1}"
6795   [(set_attr "type" "alu1")
6796    (set_attr "mode" "QI")])
6798 (define_insn "*subqi_2"
6799   [(set (reg FLAGS_REG)
6800         (compare
6801           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6802                     (match_operand:QI 2 "general_operand" "qi,qm"))
6803           (const_int 0)))
6804    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6805         (minus:HI (match_dup 1) (match_dup 2)))]
6806   "ix86_match_ccmode (insn, CCGOCmode)
6807    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6808   "sub{b}\t{%2, %0|%0, %2}"
6809   [(set_attr "type" "alu")
6810    (set_attr "mode" "QI")])
6812 (define_insn "*subqi_3"
6813   [(set (reg FLAGS_REG)
6814         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6815                  (match_operand:QI 2 "general_operand" "qi,qm")))
6816    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6817         (minus:HI (match_dup 1) (match_dup 2)))]
6818   "ix86_match_ccmode (insn, CCmode)
6819    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6820   "sub{b}\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "alu")
6822    (set_attr "mode" "QI")])
6824 ;; The patterns that match these are at the end of this file.
6826 (define_expand "subxf3"
6827   [(set (match_operand:XF 0 "register_operand" "")
6828         (minus:XF (match_operand:XF 1 "register_operand" "")
6829                   (match_operand:XF 2 "register_operand" "")))]
6830   "TARGET_80387"
6831   "")
6833 (define_expand "subdf3"
6834   [(set (match_operand:DF 0 "register_operand" "")
6835         (minus:DF (match_operand:DF 1 "register_operand" "")
6836                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6837   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6838   "")
6840 (define_expand "subsf3"
6841   [(set (match_operand:SF 0 "register_operand" "")
6842         (minus:SF (match_operand:SF 1 "register_operand" "")
6843                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6844   "TARGET_80387 || TARGET_SSE_MATH"
6845   "")
6847 ;; Multiply instructions
6849 (define_expand "muldi3"
6850   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6851                    (mult:DI (match_operand:DI 1 "register_operand" "")
6852                             (match_operand:DI 2 "x86_64_general_operand" "")))
6853               (clobber (reg:CC FLAGS_REG))])]
6854   "TARGET_64BIT"
6855   "")
6857 (define_insn "*muldi3_1_rex64"
6858   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6859         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6860                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6861    (clobber (reg:CC FLAGS_REG))]
6862   "TARGET_64BIT
6863    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6864   "@
6865    imul{q}\t{%2, %1, %0|%0, %1, %2}
6866    imul{q}\t{%2, %1, %0|%0, %1, %2}
6867    imul{q}\t{%2, %0|%0, %2}"
6868   [(set_attr "type" "imul")
6869    (set_attr "prefix_0f" "0,0,1")
6870    (set (attr "athlon_decode")
6871         (cond [(eq_attr "cpu" "athlon")
6872                   (const_string "vector")
6873                (eq_attr "alternative" "1")
6874                   (const_string "vector")
6875                (and (eq_attr "alternative" "2")
6876                     (match_operand 1 "memory_operand" ""))
6877                   (const_string "vector")]
6878               (const_string "direct")))
6879    (set_attr "mode" "DI")])
6881 (define_expand "mulsi3"
6882   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6883                    (mult:SI (match_operand:SI 1 "register_operand" "")
6884                             (match_operand:SI 2 "general_operand" "")))
6885               (clobber (reg:CC FLAGS_REG))])]
6886   ""
6887   "")
6889 (define_insn "*mulsi3_1"
6890   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6891         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6892                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6893    (clobber (reg:CC FLAGS_REG))]
6894   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6895   "@
6896    imul{l}\t{%2, %1, %0|%0, %1, %2}
6897    imul{l}\t{%2, %1, %0|%0, %1, %2}
6898    imul{l}\t{%2, %0|%0, %2}"
6899   [(set_attr "type" "imul")
6900    (set_attr "prefix_0f" "0,0,1")
6901    (set (attr "athlon_decode")
6902         (cond [(eq_attr "cpu" "athlon")
6903                   (const_string "vector")
6904                (eq_attr "alternative" "1")
6905                   (const_string "vector")
6906                (and (eq_attr "alternative" "2")
6907                     (match_operand 1 "memory_operand" ""))
6908                   (const_string "vector")]
6909               (const_string "direct")))
6910    (set_attr "mode" "SI")])
6912 (define_insn "*mulsi3_1_zext"
6913   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6914         (zero_extend:DI
6915           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6916                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6917    (clobber (reg:CC FLAGS_REG))]
6918   "TARGET_64BIT
6919    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6920   "@
6921    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6923    imul{l}\t{%2, %k0|%k0, %2}"
6924   [(set_attr "type" "imul")
6925    (set_attr "prefix_0f" "0,0,1")
6926    (set (attr "athlon_decode")
6927         (cond [(eq_attr "cpu" "athlon")
6928                   (const_string "vector")
6929                (eq_attr "alternative" "1")
6930                   (const_string "vector")
6931                (and (eq_attr "alternative" "2")
6932                     (match_operand 1 "memory_operand" ""))
6933                   (const_string "vector")]
6934               (const_string "direct")))
6935    (set_attr "mode" "SI")])
6937 (define_expand "mulhi3"
6938   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6939                    (mult:HI (match_operand:HI 1 "register_operand" "")
6940                             (match_operand:HI 2 "general_operand" "")))
6941               (clobber (reg:CC FLAGS_REG))])]
6942   "TARGET_HIMODE_MATH"
6943   "")
6945 (define_insn "*mulhi3_1"
6946   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6947         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6948                  (match_operand:HI 2 "general_operand" "K,i,mr")))
6949    (clobber (reg:CC FLAGS_REG))]
6950   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6951   "@
6952    imul{w}\t{%2, %1, %0|%0, %1, %2}
6953    imul{w}\t{%2, %1, %0|%0, %1, %2}
6954    imul{w}\t{%2, %0|%0, %2}"
6955   [(set_attr "type" "imul")
6956    (set_attr "prefix_0f" "0,0,1")
6957    (set (attr "athlon_decode")
6958         (cond [(eq_attr "cpu" "athlon")
6959                   (const_string "vector")
6960                (eq_attr "alternative" "1,2")
6961                   (const_string "vector")]
6962               (const_string "direct")))
6963    (set_attr "mode" "HI")])
6965 (define_expand "mulqi3"
6966   [(parallel [(set (match_operand:QI 0 "register_operand" "")
6967                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6968                             (match_operand:QI 2 "register_operand" "")))
6969               (clobber (reg:CC FLAGS_REG))])]
6970   "TARGET_QIMODE_MATH"
6971   "")
6973 (define_insn "*mulqi3_1"
6974   [(set (match_operand:QI 0 "register_operand" "=a")
6975         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6976                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6977    (clobber (reg:CC FLAGS_REG))]
6978   "TARGET_QIMODE_MATH
6979    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6980   "mul{b}\t%2"
6981   [(set_attr "type" "imul")
6982    (set_attr "length_immediate" "0")
6983    (set (attr "athlon_decode")
6984      (if_then_else (eq_attr "cpu" "athlon")
6985         (const_string "vector")
6986         (const_string "direct")))
6987    (set_attr "mode" "QI")])
6989 (define_expand "umulqihi3"
6990   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6991                    (mult:HI (zero_extend:HI
6992                               (match_operand:QI 1 "nonimmediate_operand" ""))
6993                             (zero_extend:HI
6994                               (match_operand:QI 2 "register_operand" ""))))
6995               (clobber (reg:CC FLAGS_REG))])]
6996   "TARGET_QIMODE_MATH"
6997   "")
6999 (define_insn "*umulqihi3_1"
7000   [(set (match_operand:HI 0 "register_operand" "=a")
7001         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7002                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7003    (clobber (reg:CC FLAGS_REG))]
7004   "TARGET_QIMODE_MATH
7005    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7006   "mul{b}\t%2"
7007   [(set_attr "type" "imul")
7008    (set_attr "length_immediate" "0")
7009    (set (attr "athlon_decode")
7010      (if_then_else (eq_attr "cpu" "athlon")
7011         (const_string "vector")
7012         (const_string "direct")))
7013    (set_attr "mode" "QI")])
7015 (define_expand "mulqihi3"
7016   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7017                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7018                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7019               (clobber (reg:CC FLAGS_REG))])]
7020   "TARGET_QIMODE_MATH"
7021   "")
7023 (define_insn "*mulqihi3_insn"
7024   [(set (match_operand:HI 0 "register_operand" "=a")
7025         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7026                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7027    (clobber (reg:CC FLAGS_REG))]
7028   "TARGET_QIMODE_MATH
7029    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7030   "imul{b}\t%2"
7031   [(set_attr "type" "imul")
7032    (set_attr "length_immediate" "0")
7033    (set (attr "athlon_decode")
7034      (if_then_else (eq_attr "cpu" "athlon")
7035         (const_string "vector")
7036         (const_string "direct")))
7037    (set_attr "mode" "QI")])
7039 (define_expand "umulditi3"
7040   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7041                    (mult:TI (zero_extend:TI
7042                               (match_operand:DI 1 "nonimmediate_operand" ""))
7043                             (zero_extend:TI
7044                               (match_operand:DI 2 "register_operand" ""))))
7045               (clobber (reg:CC FLAGS_REG))])]
7046   "TARGET_64BIT"
7047   "")
7049 (define_insn "*umulditi3_insn"
7050   [(set (match_operand:TI 0 "register_operand" "=A")
7051         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7052                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7053    (clobber (reg:CC FLAGS_REG))]
7054   "TARGET_64BIT
7055    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7056   "mul{q}\t%2"
7057   [(set_attr "type" "imul")
7058    (set_attr "length_immediate" "0")
7059    (set (attr "athlon_decode")
7060      (if_then_else (eq_attr "cpu" "athlon")
7061         (const_string "vector")
7062         (const_string "double")))
7063    (set_attr "mode" "DI")])
7065 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7066 (define_expand "umulsidi3"
7067   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7068                    (mult:DI (zero_extend:DI
7069                               (match_operand:SI 1 "nonimmediate_operand" ""))
7070                             (zero_extend:DI
7071                               (match_operand:SI 2 "register_operand" ""))))
7072               (clobber (reg:CC FLAGS_REG))])]
7073   "!TARGET_64BIT"
7074   "")
7076 (define_insn "*umulsidi3_insn"
7077   [(set (match_operand:DI 0 "register_operand" "=A")
7078         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7079                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7080    (clobber (reg:CC FLAGS_REG))]
7081   "!TARGET_64BIT
7082    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7083   "mul{l}\t%2"
7084   [(set_attr "type" "imul")
7085    (set_attr "length_immediate" "0")
7086    (set (attr "athlon_decode")
7087      (if_then_else (eq_attr "cpu" "athlon")
7088         (const_string "vector")
7089         (const_string "double")))
7090    (set_attr "mode" "SI")])
7092 (define_expand "mulditi3"
7093   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7094                    (mult:TI (sign_extend:TI
7095                               (match_operand:DI 1 "nonimmediate_operand" ""))
7096                             (sign_extend:TI
7097                               (match_operand:DI 2 "register_operand" ""))))
7098               (clobber (reg:CC FLAGS_REG))])]
7099   "TARGET_64BIT"
7100   "")
7102 (define_insn "*mulditi3_insn"
7103   [(set (match_operand:TI 0 "register_operand" "=A")
7104         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7105                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7106    (clobber (reg:CC FLAGS_REG))]
7107   "TARGET_64BIT
7108    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7109   "imul{q}\t%2"
7110   [(set_attr "type" "imul")
7111    (set_attr "length_immediate" "0")
7112    (set (attr "athlon_decode")
7113      (if_then_else (eq_attr "cpu" "athlon")
7114         (const_string "vector")
7115         (const_string "double")))
7116    (set_attr "mode" "DI")])
7118 (define_expand "mulsidi3"
7119   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7120                    (mult:DI (sign_extend:DI
7121                               (match_operand:SI 1 "nonimmediate_operand" ""))
7122                             (sign_extend:DI
7123                               (match_operand:SI 2 "register_operand" ""))))
7124               (clobber (reg:CC FLAGS_REG))])]
7125   "!TARGET_64BIT"
7126   "")
7128 (define_insn "*mulsidi3_insn"
7129   [(set (match_operand:DI 0 "register_operand" "=A")
7130         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7131                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7132    (clobber (reg:CC FLAGS_REG))]
7133   "!TARGET_64BIT
7134    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7135   "imul{l}\t%2"
7136   [(set_attr "type" "imul")
7137    (set_attr "length_immediate" "0")
7138    (set (attr "athlon_decode")
7139      (if_then_else (eq_attr "cpu" "athlon")
7140         (const_string "vector")
7141         (const_string "double")))
7142    (set_attr "mode" "SI")])
7144 (define_expand "umuldi3_highpart"
7145   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7146                    (truncate:DI
7147                      (lshiftrt:TI
7148                        (mult:TI (zero_extend:TI
7149                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7150                                 (zero_extend:TI
7151                                   (match_operand:DI 2 "register_operand" "")))
7152                        (const_int 64))))
7153               (clobber (match_scratch:DI 3 ""))
7154               (clobber (reg:CC FLAGS_REG))])]
7155   "TARGET_64BIT"
7156   "")
7158 (define_insn "*umuldi3_highpart_rex64"
7159   [(set (match_operand:DI 0 "register_operand" "=d")
7160         (truncate:DI
7161           (lshiftrt:TI
7162             (mult:TI (zero_extend:TI
7163                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7164                      (zero_extend:TI
7165                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7166             (const_int 64))))
7167    (clobber (match_scratch:DI 3 "=1"))
7168    (clobber (reg:CC FLAGS_REG))]
7169   "TARGET_64BIT
7170    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7171   "mul{q}\t%2"
7172   [(set_attr "type" "imul")
7173    (set_attr "length_immediate" "0")
7174    (set (attr "athlon_decode")
7175      (if_then_else (eq_attr "cpu" "athlon")
7176         (const_string "vector")
7177         (const_string "double")))
7178    (set_attr "mode" "DI")])
7180 (define_expand "umulsi3_highpart"
7181   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7182                    (truncate:SI
7183                      (lshiftrt:DI
7184                        (mult:DI (zero_extend:DI
7185                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7186                                 (zero_extend:DI
7187                                   (match_operand:SI 2 "register_operand" "")))
7188                        (const_int 32))))
7189               (clobber (match_scratch:SI 3 ""))
7190               (clobber (reg:CC FLAGS_REG))])]
7191   ""
7192   "")
7194 (define_insn "*umulsi3_highpart_insn"
7195   [(set (match_operand:SI 0 "register_operand" "=d")
7196         (truncate:SI
7197           (lshiftrt:DI
7198             (mult:DI (zero_extend:DI
7199                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7200                      (zero_extend:DI
7201                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7202             (const_int 32))))
7203    (clobber (match_scratch:SI 3 "=1"))
7204    (clobber (reg:CC FLAGS_REG))]
7205   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7206   "mul{l}\t%2"
7207   [(set_attr "type" "imul")
7208    (set_attr "length_immediate" "0")
7209    (set (attr "athlon_decode")
7210      (if_then_else (eq_attr "cpu" "athlon")
7211         (const_string "vector")
7212         (const_string "double")))
7213    (set_attr "mode" "SI")])
7215 (define_insn "*umulsi3_highpart_zext"
7216   [(set (match_operand:DI 0 "register_operand" "=d")
7217         (zero_extend:DI (truncate:SI
7218           (lshiftrt:DI
7219             (mult:DI (zero_extend:DI
7220                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7221                      (zero_extend:DI
7222                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7223             (const_int 32)))))
7224    (clobber (match_scratch:SI 3 "=1"))
7225    (clobber (reg:CC FLAGS_REG))]
7226   "TARGET_64BIT
7227    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7228   "mul{l}\t%2"
7229   [(set_attr "type" "imul")
7230    (set_attr "length_immediate" "0")
7231    (set (attr "athlon_decode")
7232      (if_then_else (eq_attr "cpu" "athlon")
7233         (const_string "vector")
7234         (const_string "double")))
7235    (set_attr "mode" "SI")])
7237 (define_expand "smuldi3_highpart"
7238   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7239                    (truncate:DI
7240                      (lshiftrt:TI
7241                        (mult:TI (sign_extend:TI
7242                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7243                                 (sign_extend:TI
7244                                   (match_operand:DI 2 "register_operand" "")))
7245                        (const_int 64))))
7246               (clobber (match_scratch:DI 3 ""))
7247               (clobber (reg:CC FLAGS_REG))])]
7248   "TARGET_64BIT"
7249   "")
7251 (define_insn "*smuldi3_highpart_rex64"
7252   [(set (match_operand:DI 0 "register_operand" "=d")
7253         (truncate:DI
7254           (lshiftrt:TI
7255             (mult:TI (sign_extend:TI
7256                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7257                      (sign_extend:TI
7258                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7259             (const_int 64))))
7260    (clobber (match_scratch:DI 3 "=1"))
7261    (clobber (reg:CC FLAGS_REG))]
7262   "TARGET_64BIT
7263    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7264   "imul{q}\t%2"
7265   [(set_attr "type" "imul")
7266    (set (attr "athlon_decode")
7267      (if_then_else (eq_attr "cpu" "athlon")
7268         (const_string "vector")
7269         (const_string "double")))
7270    (set_attr "mode" "DI")])
7272 (define_expand "smulsi3_highpart"
7273   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7274                    (truncate:SI
7275                      (lshiftrt:DI
7276                        (mult:DI (sign_extend:DI
7277                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7278                                 (sign_extend:DI
7279                                   (match_operand:SI 2 "register_operand" "")))
7280                        (const_int 32))))
7281               (clobber (match_scratch:SI 3 ""))
7282               (clobber (reg:CC FLAGS_REG))])]
7283   ""
7284   "")
7286 (define_insn "*smulsi3_highpart_insn"
7287   [(set (match_operand:SI 0 "register_operand" "=d")
7288         (truncate:SI
7289           (lshiftrt:DI
7290             (mult:DI (sign_extend:DI
7291                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7292                      (sign_extend:DI
7293                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7294             (const_int 32))))
7295    (clobber (match_scratch:SI 3 "=1"))
7296    (clobber (reg:CC FLAGS_REG))]
7297   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7298   "imul{l}\t%2"
7299   [(set_attr "type" "imul")
7300    (set (attr "athlon_decode")
7301      (if_then_else (eq_attr "cpu" "athlon")
7302         (const_string "vector")
7303         (const_string "double")))
7304    (set_attr "mode" "SI")])
7306 (define_insn "*smulsi3_highpart_zext"
7307   [(set (match_operand:DI 0 "register_operand" "=d")
7308         (zero_extend:DI (truncate:SI
7309           (lshiftrt:DI
7310             (mult:DI (sign_extend:DI
7311                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7312                      (sign_extend:DI
7313                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7314             (const_int 32)))))
7315    (clobber (match_scratch:SI 3 "=1"))
7316    (clobber (reg:CC FLAGS_REG))]
7317   "TARGET_64BIT
7318    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7319   "imul{l}\t%2"
7320   [(set_attr "type" "imul")
7321    (set (attr "athlon_decode")
7322      (if_then_else (eq_attr "cpu" "athlon")
7323         (const_string "vector")
7324         (const_string "double")))
7325    (set_attr "mode" "SI")])
7327 ;; The patterns that match these are at the end of this file.
7329 (define_expand "mulxf3"
7330   [(set (match_operand:XF 0 "register_operand" "")
7331         (mult:XF (match_operand:XF 1 "register_operand" "")
7332                  (match_operand:XF 2 "register_operand" "")))]
7333   "TARGET_80387"
7334   "")
7336 (define_expand "muldf3"
7337   [(set (match_operand:DF 0 "register_operand" "")
7338         (mult:DF (match_operand:DF 1 "register_operand" "")
7339                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7340   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7341   "")
7343 (define_expand "mulsf3"
7344   [(set (match_operand:SF 0 "register_operand" "")
7345         (mult:SF (match_operand:SF 1 "register_operand" "")
7346                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7347   "TARGET_80387 || TARGET_SSE_MATH"
7348   "")
7350 ;; Divide instructions
7352 (define_insn "divqi3"
7353   [(set (match_operand:QI 0 "register_operand" "=a")
7354         (div:QI (match_operand:HI 1 "register_operand" "0")
7355                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7356    (clobber (reg:CC FLAGS_REG))]
7357   "TARGET_QIMODE_MATH"
7358   "idiv{b}\t%2"
7359   [(set_attr "type" "idiv")
7360    (set_attr "mode" "QI")])
7362 (define_insn "udivqi3"
7363   [(set (match_operand:QI 0 "register_operand" "=a")
7364         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7365                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7366    (clobber (reg:CC FLAGS_REG))]
7367   "TARGET_QIMODE_MATH"
7368   "div{b}\t%2"
7369   [(set_attr "type" "idiv")
7370    (set_attr "mode" "QI")])
7372 ;; The patterns that match these are at the end of this file.
7374 (define_expand "divxf3"
7375   [(set (match_operand:XF 0 "register_operand" "")
7376         (div:XF (match_operand:XF 1 "register_operand" "")
7377                 (match_operand:XF 2 "register_operand" "")))]
7378   "TARGET_80387"
7379   "")
7381 (define_expand "divdf3"
7382   [(set (match_operand:DF 0 "register_operand" "")
7383         (div:DF (match_operand:DF 1 "register_operand" "")
7384                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7385    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7386    "")
7388 (define_expand "divsf3"
7389   [(set (match_operand:SF 0 "register_operand" "")
7390         (div:SF (match_operand:SF 1 "register_operand" "")
7391                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7392   "TARGET_80387 || TARGET_SSE_MATH"
7393   "")
7395 ;; Remainder instructions.
7397 (define_expand "divmoddi4"
7398   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7399                    (div:DI (match_operand:DI 1 "register_operand" "")
7400                            (match_operand:DI 2 "nonimmediate_operand" "")))
7401               (set (match_operand:DI 3 "register_operand" "")
7402                    (mod:DI (match_dup 1) (match_dup 2)))
7403               (clobber (reg:CC FLAGS_REG))])]
7404   "TARGET_64BIT"
7405   "")
7407 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7408 ;; Penalize eax case slightly because it results in worse scheduling
7409 ;; of code.
7410 (define_insn "*divmoddi4_nocltd_rex64"
7411   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7412         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7413                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7414    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7415         (mod:DI (match_dup 2) (match_dup 3)))
7416    (clobber (reg:CC FLAGS_REG))]
7417   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7418   "#"
7419   [(set_attr "type" "multi")])
7421 (define_insn "*divmoddi4_cltd_rex64"
7422   [(set (match_operand:DI 0 "register_operand" "=a")
7423         (div:DI (match_operand:DI 2 "register_operand" "a")
7424                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7425    (set (match_operand:DI 1 "register_operand" "=&d")
7426         (mod:DI (match_dup 2) (match_dup 3)))
7427    (clobber (reg:CC FLAGS_REG))]
7428   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7429   "#"
7430   [(set_attr "type" "multi")])
7432 (define_insn "*divmoddi_noext_rex64"
7433   [(set (match_operand:DI 0 "register_operand" "=a")
7434         (div:DI (match_operand:DI 1 "register_operand" "0")
7435                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7436    (set (match_operand:DI 3 "register_operand" "=d")
7437         (mod:DI (match_dup 1) (match_dup 2)))
7438    (use (match_operand:DI 4 "register_operand" "3"))
7439    (clobber (reg:CC FLAGS_REG))]
7440   "TARGET_64BIT"
7441   "idiv{q}\t%2"
7442   [(set_attr "type" "idiv")
7443    (set_attr "mode" "DI")])
7445 (define_split
7446   [(set (match_operand:DI 0 "register_operand" "")
7447         (div:DI (match_operand:DI 1 "register_operand" "")
7448                 (match_operand:DI 2 "nonimmediate_operand" "")))
7449    (set (match_operand:DI 3 "register_operand" "")
7450         (mod:DI (match_dup 1) (match_dup 2)))
7451    (clobber (reg:CC FLAGS_REG))]
7452   "TARGET_64BIT && reload_completed"
7453   [(parallel [(set (match_dup 3)
7454                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7455               (clobber (reg:CC FLAGS_REG))])
7456    (parallel [(set (match_dup 0)
7457                    (div:DI (reg:DI 0) (match_dup 2)))
7458               (set (match_dup 3)
7459                    (mod:DI (reg:DI 0) (match_dup 2)))
7460               (use (match_dup 3))
7461               (clobber (reg:CC FLAGS_REG))])]
7463   /* Avoid use of cltd in favor of a mov+shift.  */
7464   if (!TARGET_USE_CLTD && !optimize_size)
7465     {
7466       if (true_regnum (operands[1]))
7467         emit_move_insn (operands[0], operands[1]);
7468       else
7469         emit_move_insn (operands[3], operands[1]);
7470       operands[4] = operands[3];
7471     }
7472   else
7473     {
7474       gcc_assert (!true_regnum (operands[1]));
7475       operands[4] = operands[1];
7476     }
7480 (define_expand "divmodsi4"
7481   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7482                    (div:SI (match_operand:SI 1 "register_operand" "")
7483                            (match_operand:SI 2 "nonimmediate_operand" "")))
7484               (set (match_operand:SI 3 "register_operand" "")
7485                    (mod:SI (match_dup 1) (match_dup 2)))
7486               (clobber (reg:CC FLAGS_REG))])]
7487   ""
7488   "")
7490 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7491 ;; Penalize eax case slightly because it results in worse scheduling
7492 ;; of code.
7493 (define_insn "*divmodsi4_nocltd"
7494   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7495         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7496                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7497    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7498         (mod:SI (match_dup 2) (match_dup 3)))
7499    (clobber (reg:CC FLAGS_REG))]
7500   "!optimize_size && !TARGET_USE_CLTD"
7501   "#"
7502   [(set_attr "type" "multi")])
7504 (define_insn "*divmodsi4_cltd"
7505   [(set (match_operand:SI 0 "register_operand" "=a")
7506         (div:SI (match_operand:SI 2 "register_operand" "a")
7507                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7508    (set (match_operand:SI 1 "register_operand" "=&d")
7509         (mod:SI (match_dup 2) (match_dup 3)))
7510    (clobber (reg:CC FLAGS_REG))]
7511   "optimize_size || TARGET_USE_CLTD"
7512   "#"
7513   [(set_attr "type" "multi")])
7515 (define_insn "*divmodsi_noext"
7516   [(set (match_operand:SI 0 "register_operand" "=a")
7517         (div:SI (match_operand:SI 1 "register_operand" "0")
7518                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7519    (set (match_operand:SI 3 "register_operand" "=d")
7520         (mod:SI (match_dup 1) (match_dup 2)))
7521    (use (match_operand:SI 4 "register_operand" "3"))
7522    (clobber (reg:CC FLAGS_REG))]
7523   ""
7524   "idiv{l}\t%2"
7525   [(set_attr "type" "idiv")
7526    (set_attr "mode" "SI")])
7528 (define_split
7529   [(set (match_operand:SI 0 "register_operand" "")
7530         (div:SI (match_operand:SI 1 "register_operand" "")
7531                 (match_operand:SI 2 "nonimmediate_operand" "")))
7532    (set (match_operand:SI 3 "register_operand" "")
7533         (mod:SI (match_dup 1) (match_dup 2)))
7534    (clobber (reg:CC FLAGS_REG))]
7535   "reload_completed"
7536   [(parallel [(set (match_dup 3)
7537                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7538               (clobber (reg:CC FLAGS_REG))])
7539    (parallel [(set (match_dup 0)
7540                    (div:SI (reg:SI 0) (match_dup 2)))
7541               (set (match_dup 3)
7542                    (mod:SI (reg:SI 0) (match_dup 2)))
7543               (use (match_dup 3))
7544               (clobber (reg:CC FLAGS_REG))])]
7546   /* Avoid use of cltd in favor of a mov+shift.  */
7547   if (!TARGET_USE_CLTD && !optimize_size)
7548     {
7549       if (true_regnum (operands[1]))
7550         emit_move_insn (operands[0], operands[1]);
7551       else
7552         emit_move_insn (operands[3], operands[1]);
7553       operands[4] = operands[3];
7554     }
7555   else
7556     {
7557       gcc_assert (!true_regnum (operands[1]));
7558       operands[4] = operands[1];
7559     }
7561 ;; %%% Split me.
7562 (define_insn "divmodhi4"
7563   [(set (match_operand:HI 0 "register_operand" "=a")
7564         (div:HI (match_operand:HI 1 "register_operand" "0")
7565                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7566    (set (match_operand:HI 3 "register_operand" "=&d")
7567         (mod:HI (match_dup 1) (match_dup 2)))
7568    (clobber (reg:CC FLAGS_REG))]
7569   "TARGET_HIMODE_MATH"
7570   "cwtd\;idiv{w}\t%2"
7571   [(set_attr "type" "multi")
7572    (set_attr "length_immediate" "0")
7573    (set_attr "mode" "SI")])
7575 (define_insn "udivmoddi4"
7576   [(set (match_operand:DI 0 "register_operand" "=a")
7577         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7578                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7579    (set (match_operand:DI 3 "register_operand" "=&d")
7580         (umod:DI (match_dup 1) (match_dup 2)))
7581    (clobber (reg:CC FLAGS_REG))]
7582   "TARGET_64BIT"
7583   "xor{q}\t%3, %3\;div{q}\t%2"
7584   [(set_attr "type" "multi")
7585    (set_attr "length_immediate" "0")
7586    (set_attr "mode" "DI")])
7588 (define_insn "*udivmoddi4_noext"
7589   [(set (match_operand:DI 0 "register_operand" "=a")
7590         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7591                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7592    (set (match_operand:DI 3 "register_operand" "=d")
7593         (umod:DI (match_dup 1) (match_dup 2)))
7594    (use (match_dup 3))
7595    (clobber (reg:CC FLAGS_REG))]
7596   "TARGET_64BIT"
7597   "div{q}\t%2"
7598   [(set_attr "type" "idiv")
7599    (set_attr "mode" "DI")])
7601 (define_split
7602   [(set (match_operand:DI 0 "register_operand" "")
7603         (udiv:DI (match_operand:DI 1 "register_operand" "")
7604                  (match_operand:DI 2 "nonimmediate_operand" "")))
7605    (set (match_operand:DI 3 "register_operand" "")
7606         (umod:DI (match_dup 1) (match_dup 2)))
7607    (clobber (reg:CC FLAGS_REG))]
7608   "TARGET_64BIT && reload_completed"
7609   [(set (match_dup 3) (const_int 0))
7610    (parallel [(set (match_dup 0)
7611                    (udiv:DI (match_dup 1) (match_dup 2)))
7612               (set (match_dup 3)
7613                    (umod:DI (match_dup 1) (match_dup 2)))
7614               (use (match_dup 3))
7615               (clobber (reg:CC FLAGS_REG))])]
7616   "")
7618 (define_insn "udivmodsi4"
7619   [(set (match_operand:SI 0 "register_operand" "=a")
7620         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7621                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7622    (set (match_operand:SI 3 "register_operand" "=&d")
7623         (umod:SI (match_dup 1) (match_dup 2)))
7624    (clobber (reg:CC FLAGS_REG))]
7625   ""
7626   "xor{l}\t%3, %3\;div{l}\t%2"
7627   [(set_attr "type" "multi")
7628    (set_attr "length_immediate" "0")
7629    (set_attr "mode" "SI")])
7631 (define_insn "*udivmodsi4_noext"
7632   [(set (match_operand:SI 0 "register_operand" "=a")
7633         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7634                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7635    (set (match_operand:SI 3 "register_operand" "=d")
7636         (umod:SI (match_dup 1) (match_dup 2)))
7637    (use (match_dup 3))
7638    (clobber (reg:CC FLAGS_REG))]
7639   ""
7640   "div{l}\t%2"
7641   [(set_attr "type" "idiv")
7642    (set_attr "mode" "SI")])
7644 (define_split
7645   [(set (match_operand:SI 0 "register_operand" "")
7646         (udiv:SI (match_operand:SI 1 "register_operand" "")
7647                  (match_operand:SI 2 "nonimmediate_operand" "")))
7648    (set (match_operand:SI 3 "register_operand" "")
7649         (umod:SI (match_dup 1) (match_dup 2)))
7650    (clobber (reg:CC FLAGS_REG))]
7651   "reload_completed"
7652   [(set (match_dup 3) (const_int 0))
7653    (parallel [(set (match_dup 0)
7654                    (udiv:SI (match_dup 1) (match_dup 2)))
7655               (set (match_dup 3)
7656                    (umod:SI (match_dup 1) (match_dup 2)))
7657               (use (match_dup 3))
7658               (clobber (reg:CC FLAGS_REG))])]
7659   "")
7661 (define_expand "udivmodhi4"
7662   [(set (match_dup 4) (const_int 0))
7663    (parallel [(set (match_operand:HI 0 "register_operand" "")
7664                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7665                             (match_operand:HI 2 "nonimmediate_operand" "")))
7666               (set (match_operand:HI 3 "register_operand" "")
7667                    (umod:HI (match_dup 1) (match_dup 2)))
7668               (use (match_dup 4))
7669               (clobber (reg:CC FLAGS_REG))])]
7670   "TARGET_HIMODE_MATH"
7671   "operands[4] = gen_reg_rtx (HImode);")
7673 (define_insn "*udivmodhi_noext"
7674   [(set (match_operand:HI 0 "register_operand" "=a")
7675         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7676                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7677    (set (match_operand:HI 3 "register_operand" "=d")
7678         (umod:HI (match_dup 1) (match_dup 2)))
7679    (use (match_operand:HI 4 "register_operand" "3"))
7680    (clobber (reg:CC FLAGS_REG))]
7681   ""
7682   "div{w}\t%2"
7683   [(set_attr "type" "idiv")
7684    (set_attr "mode" "HI")])
7686 ;; We cannot use div/idiv for double division, because it causes
7687 ;; "division by zero" on the overflow and that's not what we expect
7688 ;; from truncate.  Because true (non truncating) double division is
7689 ;; never generated, we can't create this insn anyway.
7691 ;(define_insn ""
7692 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7693 ;       (truncate:SI
7694 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7695 ;                  (zero_extend:DI
7696 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7697 ;   (set (match_operand:SI 3 "register_operand" "=d")
7698 ;       (truncate:SI
7699 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7700 ;   (clobber (reg:CC FLAGS_REG))]
7701 ;  ""
7702 ;  "div{l}\t{%2, %0|%0, %2}"
7703 ;  [(set_attr "type" "idiv")])
7705 ;;- Logical AND instructions
7707 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7708 ;; Note that this excludes ah.
7710 (define_insn "*testdi_1_rex64"
7711   [(set (reg FLAGS_REG)
7712         (compare
7713           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7714                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7715           (const_int 0)))]
7716   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7717    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7718   "@
7719    test{l}\t{%k1, %k0|%k0, %k1}
7720    test{l}\t{%k1, %k0|%k0, %k1}
7721    test{q}\t{%1, %0|%0, %1}
7722    test{q}\t{%1, %0|%0, %1}
7723    test{q}\t{%1, %0|%0, %1}"
7724   [(set_attr "type" "test")
7725    (set_attr "modrm" "0,1,0,1,1")
7726    (set_attr "mode" "SI,SI,DI,DI,DI")
7727    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7729 (define_insn "testsi_1"
7730   [(set (reg FLAGS_REG)
7731         (compare
7732           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7733                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7734           (const_int 0)))]
7735   "ix86_match_ccmode (insn, CCNOmode)
7736    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7737   "test{l}\t{%1, %0|%0, %1}"
7738   [(set_attr "type" "test")
7739    (set_attr "modrm" "0,1,1")
7740    (set_attr "mode" "SI")
7741    (set_attr "pent_pair" "uv,np,uv")])
7743 (define_expand "testsi_ccno_1"
7744   [(set (reg:CCNO FLAGS_REG)
7745         (compare:CCNO
7746           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7747                   (match_operand:SI 1 "nonmemory_operand" ""))
7748           (const_int 0)))]
7749   ""
7750   "")
7752 (define_insn "*testhi_1"
7753   [(set (reg FLAGS_REG)
7754         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7755                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7756                  (const_int 0)))]
7757   "ix86_match_ccmode (insn, CCNOmode)
7758    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7759   "test{w}\t{%1, %0|%0, %1}"
7760   [(set_attr "type" "test")
7761    (set_attr "modrm" "0,1,1")
7762    (set_attr "mode" "HI")
7763    (set_attr "pent_pair" "uv,np,uv")])
7765 (define_expand "testqi_ccz_1"
7766   [(set (reg:CCZ FLAGS_REG)
7767         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7768                              (match_operand:QI 1 "nonmemory_operand" ""))
7769                  (const_int 0)))]
7770   ""
7771   "")
7773 (define_insn "*testqi_1_maybe_si"
7774   [(set (reg FLAGS_REG)
7775         (compare
7776           (and:QI
7777             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7778             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7779           (const_int 0)))]
7780    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7781     && ix86_match_ccmode (insn,
7782                          GET_CODE (operands[1]) == CONST_INT
7783                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7785   if (which_alternative == 3)
7786     {
7787       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7788         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7789       return "test{l}\t{%1, %k0|%k0, %1}";
7790     }
7791   return "test{b}\t{%1, %0|%0, %1}";
7793   [(set_attr "type" "test")
7794    (set_attr "modrm" "0,1,1,1")
7795    (set_attr "mode" "QI,QI,QI,SI")
7796    (set_attr "pent_pair" "uv,np,uv,np")])
7798 (define_insn "*testqi_1"
7799   [(set (reg FLAGS_REG)
7800         (compare
7801           (and:QI
7802             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7803             (match_operand:QI 1 "general_operand" "n,n,qn"))
7804           (const_int 0)))]
7805   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7806    && ix86_match_ccmode (insn, CCNOmode)"
7807   "test{b}\t{%1, %0|%0, %1}"
7808   [(set_attr "type" "test")
7809    (set_attr "modrm" "0,1,1")
7810    (set_attr "mode" "QI")
7811    (set_attr "pent_pair" "uv,np,uv")])
7813 (define_expand "testqi_ext_ccno_0"
7814   [(set (reg:CCNO FLAGS_REG)
7815         (compare:CCNO
7816           (and:SI
7817             (zero_extract:SI
7818               (match_operand 0 "ext_register_operand" "")
7819               (const_int 8)
7820               (const_int 8))
7821             (match_operand 1 "const_int_operand" ""))
7822           (const_int 0)))]
7823   ""
7824   "")
7826 (define_insn "*testqi_ext_0"
7827   [(set (reg FLAGS_REG)
7828         (compare
7829           (and:SI
7830             (zero_extract:SI
7831               (match_operand 0 "ext_register_operand" "Q")
7832               (const_int 8)
7833               (const_int 8))
7834             (match_operand 1 "const_int_operand" "n"))
7835           (const_int 0)))]
7836   "ix86_match_ccmode (insn, CCNOmode)"
7837   "test{b}\t{%1, %h0|%h0, %1}"
7838   [(set_attr "type" "test")
7839    (set_attr "mode" "QI")
7840    (set_attr "length_immediate" "1")
7841    (set_attr "pent_pair" "np")])
7843 (define_insn "*testqi_ext_1"
7844   [(set (reg FLAGS_REG)
7845         (compare
7846           (and:SI
7847             (zero_extract:SI
7848               (match_operand 0 "ext_register_operand" "Q")
7849               (const_int 8)
7850               (const_int 8))
7851             (zero_extend:SI
7852               (match_operand:QI 1 "general_operand" "Qm")))
7853           (const_int 0)))]
7854   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7855    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7856   "test{b}\t{%1, %h0|%h0, %1}"
7857   [(set_attr "type" "test")
7858    (set_attr "mode" "QI")])
7860 (define_insn "*testqi_ext_1_rex64"
7861   [(set (reg FLAGS_REG)
7862         (compare
7863           (and:SI
7864             (zero_extract:SI
7865               (match_operand 0 "ext_register_operand" "Q")
7866               (const_int 8)
7867               (const_int 8))
7868             (zero_extend:SI
7869               (match_operand:QI 1 "register_operand" "Q")))
7870           (const_int 0)))]
7871   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7872   "test{b}\t{%1, %h0|%h0, %1}"
7873   [(set_attr "type" "test")
7874    (set_attr "mode" "QI")])
7876 (define_insn "*testqi_ext_2"
7877   [(set (reg FLAGS_REG)
7878         (compare
7879           (and:SI
7880             (zero_extract:SI
7881               (match_operand 0 "ext_register_operand" "Q")
7882               (const_int 8)
7883               (const_int 8))
7884             (zero_extract:SI
7885               (match_operand 1 "ext_register_operand" "Q")
7886               (const_int 8)
7887               (const_int 8)))
7888           (const_int 0)))]
7889   "ix86_match_ccmode (insn, CCNOmode)"
7890   "test{b}\t{%h1, %h0|%h0, %h1}"
7891   [(set_attr "type" "test")
7892    (set_attr "mode" "QI")])
7894 ;; Combine likes to form bit extractions for some tests.  Humor it.
7895 (define_insn "*testqi_ext_3"
7896   [(set (reg FLAGS_REG)
7897         (compare (zero_extract:SI
7898                    (match_operand 0 "nonimmediate_operand" "rm")
7899                    (match_operand:SI 1 "const_int_operand" "")
7900                    (match_operand:SI 2 "const_int_operand" ""))
7901                  (const_int 0)))]
7902   "ix86_match_ccmode (insn, CCNOmode)
7903    && INTVAL (operands[1]) > 0
7904    && INTVAL (operands[2]) >= 0
7905    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7906    && (GET_MODE (operands[0]) == SImode
7907        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7908        || GET_MODE (operands[0]) == HImode
7909        || GET_MODE (operands[0]) == QImode)"
7910   "#")
7912 (define_insn "*testqi_ext_3_rex64"
7913   [(set (reg FLAGS_REG)
7914         (compare (zero_extract:DI
7915                    (match_operand 0 "nonimmediate_operand" "rm")
7916                    (match_operand:DI 1 "const_int_operand" "")
7917                    (match_operand:DI 2 "const_int_operand" ""))
7918                  (const_int 0)))]
7919   "TARGET_64BIT
7920    && ix86_match_ccmode (insn, CCNOmode)
7921    && INTVAL (operands[1]) > 0
7922    && INTVAL (operands[2]) >= 0
7923    /* Ensure that resulting mask is zero or sign extended operand.  */
7924    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7925        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7926            && INTVAL (operands[1]) > 32))
7927    && (GET_MODE (operands[0]) == SImode
7928        || GET_MODE (operands[0]) == DImode
7929        || GET_MODE (operands[0]) == HImode
7930        || GET_MODE (operands[0]) == QImode)"
7931   "#")
7933 (define_split
7934   [(set (match_operand 0 "flags_reg_operand" "")
7935         (match_operator 1 "compare_operator"
7936           [(zero_extract
7937              (match_operand 2 "nonimmediate_operand" "")
7938              (match_operand 3 "const_int_operand" "")
7939              (match_operand 4 "const_int_operand" ""))
7940            (const_int 0)]))]
7941   "ix86_match_ccmode (insn, CCNOmode)"
7942   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7944   rtx val = operands[2];
7945   HOST_WIDE_INT len = INTVAL (operands[3]);
7946   HOST_WIDE_INT pos = INTVAL (operands[4]);
7947   HOST_WIDE_INT mask;
7948   enum machine_mode mode, submode;
7950   mode = GET_MODE (val);
7951   if (GET_CODE (val) == MEM)
7952     {
7953       /* ??? Combine likes to put non-volatile mem extractions in QImode
7954          no matter the size of the test.  So find a mode that works.  */
7955       if (! MEM_VOLATILE_P (val))
7956         {
7957           mode = smallest_mode_for_size (pos + len, MODE_INT);
7958           val = adjust_address (val, mode, 0);
7959         }
7960     }
7961   else if (GET_CODE (val) == SUBREG
7962            && (submode = GET_MODE (SUBREG_REG (val)),
7963                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7964            && pos + len <= GET_MODE_BITSIZE (submode))
7965     {
7966       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7967       mode = submode;
7968       val = SUBREG_REG (val);
7969     }
7970   else if (mode == HImode && pos + len <= 8)
7971     {
7972       /* Small HImode tests can be converted to QImode.  */
7973       mode = QImode;
7974       val = gen_lowpart (QImode, val);
7975     }
7977   if (len == HOST_BITS_PER_WIDE_INT)
7978     mask = -1;
7979   else
7980     mask = ((HOST_WIDE_INT)1 << len) - 1;
7981   mask <<= pos;
7983   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7986 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7987 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7988 ;; this is relatively important trick.
7989 ;; Do the conversion only post-reload to avoid limiting of the register class
7990 ;; to QI regs.
7991 (define_split
7992   [(set (match_operand 0 "flags_reg_operand" "")
7993         (match_operator 1 "compare_operator"
7994           [(and (match_operand 2 "register_operand" "")
7995                 (match_operand 3 "const_int_operand" ""))
7996            (const_int 0)]))]
7997    "reload_completed
7998     && QI_REG_P (operands[2])
7999     && GET_MODE (operands[2]) != QImode
8000     && ((ix86_match_ccmode (insn, CCZmode)
8001          && !(INTVAL (operands[3]) & ~(255 << 8)))
8002         || (ix86_match_ccmode (insn, CCNOmode)
8003             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8004   [(set (match_dup 0)
8005         (match_op_dup 1
8006           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8007                    (match_dup 3))
8008            (const_int 0)]))]
8009   "operands[2] = gen_lowpart (SImode, operands[2]);
8010    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8012 (define_split
8013   [(set (match_operand 0 "flags_reg_operand" "")
8014         (match_operator 1 "compare_operator"
8015           [(and (match_operand 2 "nonimmediate_operand" "")
8016                 (match_operand 3 "const_int_operand" ""))
8017            (const_int 0)]))]
8018    "reload_completed
8019     && GET_MODE (operands[2]) != QImode
8020     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8021     && ((ix86_match_ccmode (insn, CCZmode)
8022          && !(INTVAL (operands[3]) & ~255))
8023         || (ix86_match_ccmode (insn, CCNOmode)
8024             && !(INTVAL (operands[3]) & ~127)))"
8025   [(set (match_dup 0)
8026         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8027                          (const_int 0)]))]
8028   "operands[2] = gen_lowpart (QImode, operands[2]);
8029    operands[3] = gen_lowpart (QImode, operands[3]);")
8032 ;; %%% This used to optimize known byte-wide and operations to memory,
8033 ;; and sometimes to QImode registers.  If this is considered useful,
8034 ;; it should be done with splitters.
8036 (define_expand "anddi3"
8037   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8038         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8039                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8040    (clobber (reg:CC FLAGS_REG))]
8041   "TARGET_64BIT"
8042   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8044 (define_insn "*anddi_1_rex64"
8045   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8046         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8047                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8048    (clobber (reg:CC FLAGS_REG))]
8049   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8051   switch (get_attr_type (insn))
8052     {
8053     case TYPE_IMOVX:
8054       {
8055         enum machine_mode mode;
8057         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8058         if (INTVAL (operands[2]) == 0xff)
8059           mode = QImode;
8060         else
8061           {
8062             gcc_assert (INTVAL (operands[2]) == 0xffff);
8063             mode = HImode;
8064           }
8065         
8066         operands[1] = gen_lowpart (mode, operands[1]);
8067         if (mode == QImode)
8068           return "movz{bq|x}\t{%1,%0|%0, %1}";
8069         else
8070           return "movz{wq|x}\t{%1,%0|%0, %1}";
8071       }
8073     default:
8074       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8075       if (get_attr_mode (insn) == MODE_SI)
8076         return "and{l}\t{%k2, %k0|%k0, %k2}";
8077       else
8078         return "and{q}\t{%2, %0|%0, %2}";
8079     }
8081   [(set_attr "type" "alu,alu,alu,imovx")
8082    (set_attr "length_immediate" "*,*,*,0")
8083    (set_attr "mode" "SI,DI,DI,DI")])
8085 (define_insn "*anddi_2"
8086   [(set (reg FLAGS_REG)
8087         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8088                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8089                  (const_int 0)))
8090    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8091         (and:DI (match_dup 1) (match_dup 2)))]
8092   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8093    && ix86_binary_operator_ok (AND, DImode, operands)"
8094   "@
8095    and{l}\t{%k2, %k0|%k0, %k2}
8096    and{q}\t{%2, %0|%0, %2}
8097    and{q}\t{%2, %0|%0, %2}"
8098   [(set_attr "type" "alu")
8099    (set_attr "mode" "SI,DI,DI")])
8101 (define_expand "andsi3"
8102   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8103         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8104                 (match_operand:SI 2 "general_operand" "")))
8105    (clobber (reg:CC FLAGS_REG))]
8106   ""
8107   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8109 (define_insn "*andsi_1"
8110   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8111         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8112                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8113    (clobber (reg:CC FLAGS_REG))]
8114   "ix86_binary_operator_ok (AND, SImode, operands)"
8116   switch (get_attr_type (insn))
8117     {
8118     case TYPE_IMOVX:
8119       {
8120         enum machine_mode mode;
8122         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8123         if (INTVAL (operands[2]) == 0xff)
8124           mode = QImode;
8125         else
8126           {
8127             gcc_assert (INTVAL (operands[2]) == 0xffff);
8128             mode = HImode;
8129           }
8130         
8131         operands[1] = gen_lowpart (mode, operands[1]);
8132         if (mode == QImode)
8133           return "movz{bl|x}\t{%1,%0|%0, %1}";
8134         else
8135           return "movz{wl|x}\t{%1,%0|%0, %1}";
8136       }
8138     default:
8139       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8140       return "and{l}\t{%2, %0|%0, %2}";
8141     }
8143   [(set_attr "type" "alu,alu,imovx")
8144    (set_attr "length_immediate" "*,*,0")
8145    (set_attr "mode" "SI")])
8147 (define_split
8148   [(set (match_operand 0 "register_operand" "")
8149         (and (match_dup 0)
8150              (const_int -65536)))
8151    (clobber (reg:CC FLAGS_REG))]
8152   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8153   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8154   "operands[1] = gen_lowpart (HImode, operands[0]);")
8156 (define_split
8157   [(set (match_operand 0 "ext_register_operand" "")
8158         (and (match_dup 0)
8159              (const_int -256)))
8160    (clobber (reg:CC FLAGS_REG))]
8161   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8162   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8163   "operands[1] = gen_lowpart (QImode, operands[0]);")
8165 (define_split
8166   [(set (match_operand 0 "ext_register_operand" "")
8167         (and (match_dup 0)
8168              (const_int -65281)))
8169    (clobber (reg:CC FLAGS_REG))]
8170   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8171   [(parallel [(set (zero_extract:SI (match_dup 0)
8172                                     (const_int 8)
8173                                     (const_int 8))
8174                    (xor:SI 
8175                      (zero_extract:SI (match_dup 0)
8176                                       (const_int 8)
8177                                       (const_int 8))
8178                      (zero_extract:SI (match_dup 0)
8179                                       (const_int 8)
8180                                       (const_int 8))))
8181               (clobber (reg:CC FLAGS_REG))])]
8182   "operands[0] = gen_lowpart (SImode, operands[0]);")
8184 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8185 (define_insn "*andsi_1_zext"
8186   [(set (match_operand:DI 0 "register_operand" "=r")
8187         (zero_extend:DI
8188           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8189                   (match_operand:SI 2 "general_operand" "rim"))))
8190    (clobber (reg:CC FLAGS_REG))]
8191   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8192   "and{l}\t{%2, %k0|%k0, %2}"
8193   [(set_attr "type" "alu")
8194    (set_attr "mode" "SI")])
8196 (define_insn "*andsi_2"
8197   [(set (reg FLAGS_REG)
8198         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8199                          (match_operand:SI 2 "general_operand" "rim,ri"))
8200                  (const_int 0)))
8201    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8202         (and:SI (match_dup 1) (match_dup 2)))]
8203   "ix86_match_ccmode (insn, CCNOmode)
8204    && ix86_binary_operator_ok (AND, SImode, operands)"
8205   "and{l}\t{%2, %0|%0, %2}"
8206   [(set_attr "type" "alu")
8207    (set_attr "mode" "SI")])
8209 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8210 (define_insn "*andsi_2_zext"
8211   [(set (reg FLAGS_REG)
8212         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8213                          (match_operand:SI 2 "general_operand" "rim"))
8214                  (const_int 0)))
8215    (set (match_operand:DI 0 "register_operand" "=r")
8216         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8217   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8218    && ix86_binary_operator_ok (AND, SImode, operands)"
8219   "and{l}\t{%2, %k0|%k0, %2}"
8220   [(set_attr "type" "alu")
8221    (set_attr "mode" "SI")])
8223 (define_expand "andhi3"
8224   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8225         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8226                 (match_operand:HI 2 "general_operand" "")))
8227    (clobber (reg:CC FLAGS_REG))]
8228   "TARGET_HIMODE_MATH"
8229   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8231 (define_insn "*andhi_1"
8232   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8233         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8234                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8235    (clobber (reg:CC FLAGS_REG))]
8236   "ix86_binary_operator_ok (AND, HImode, operands)"
8238   switch (get_attr_type (insn))
8239     {
8240     case TYPE_IMOVX:
8241       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8242       gcc_assert (INTVAL (operands[2]) == 0xff);
8243       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8245     default:
8246       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8248       return "and{w}\t{%2, %0|%0, %2}";
8249     }
8251   [(set_attr "type" "alu,alu,imovx")
8252    (set_attr "length_immediate" "*,*,0")
8253    (set_attr "mode" "HI,HI,SI")])
8255 (define_insn "*andhi_2"
8256   [(set (reg FLAGS_REG)
8257         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8258                          (match_operand:HI 2 "general_operand" "rim,ri"))
8259                  (const_int 0)))
8260    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8261         (and:HI (match_dup 1) (match_dup 2)))]
8262   "ix86_match_ccmode (insn, CCNOmode)
8263    && ix86_binary_operator_ok (AND, HImode, operands)"
8264   "and{w}\t{%2, %0|%0, %2}"
8265   [(set_attr "type" "alu")
8266    (set_attr "mode" "HI")])
8268 (define_expand "andqi3"
8269   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8270         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8271                 (match_operand:QI 2 "general_operand" "")))
8272    (clobber (reg:CC FLAGS_REG))]
8273   "TARGET_QIMODE_MATH"
8274   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8276 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8277 (define_insn "*andqi_1"
8278   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8279         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8280                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8281    (clobber (reg:CC FLAGS_REG))]
8282   "ix86_binary_operator_ok (AND, QImode, operands)"
8283   "@
8284    and{b}\t{%2, %0|%0, %2}
8285    and{b}\t{%2, %0|%0, %2}
8286    and{l}\t{%k2, %k0|%k0, %k2}"
8287   [(set_attr "type" "alu")
8288    (set_attr "mode" "QI,QI,SI")])
8290 (define_insn "*andqi_1_slp"
8291   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8292         (and:QI (match_dup 0)
8293                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8294    (clobber (reg:CC FLAGS_REG))]
8295   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8296    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8297   "and{b}\t{%1, %0|%0, %1}"
8298   [(set_attr "type" "alu1")
8299    (set_attr "mode" "QI")])
8301 (define_insn "*andqi_2_maybe_si"
8302   [(set (reg FLAGS_REG)
8303         (compare (and:QI
8304                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8305                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8306                  (const_int 0)))
8307    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8308         (and:QI (match_dup 1) (match_dup 2)))]
8309   "ix86_binary_operator_ok (AND, QImode, operands)
8310    && ix86_match_ccmode (insn,
8311                          GET_CODE (operands[2]) == CONST_INT
8312                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8314   if (which_alternative == 2)
8315     {
8316       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8317         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8318       return "and{l}\t{%2, %k0|%k0, %2}";
8319     }
8320   return "and{b}\t{%2, %0|%0, %2}";
8322   [(set_attr "type" "alu")
8323    (set_attr "mode" "QI,QI,SI")])
8325 (define_insn "*andqi_2"
8326   [(set (reg FLAGS_REG)
8327         (compare (and:QI
8328                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8329                    (match_operand:QI 2 "general_operand" "qim,qi"))
8330                  (const_int 0)))
8331    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8332         (and:QI (match_dup 1) (match_dup 2)))]
8333   "ix86_match_ccmode (insn, CCNOmode)
8334    && ix86_binary_operator_ok (AND, QImode, operands)"
8335   "and{b}\t{%2, %0|%0, %2}"
8336   [(set_attr "type" "alu")
8337    (set_attr "mode" "QI")])
8339 (define_insn "*andqi_2_slp"
8340   [(set (reg FLAGS_REG)
8341         (compare (and:QI
8342                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8343                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8344                  (const_int 0)))
8345    (set (strict_low_part (match_dup 0))
8346         (and:QI (match_dup 0) (match_dup 1)))]
8347   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8348    && ix86_match_ccmode (insn, CCNOmode)
8349    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8350   "and{b}\t{%1, %0|%0, %1}"
8351   [(set_attr "type" "alu1")
8352    (set_attr "mode" "QI")])
8354 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8355 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8356 ;; for a QImode operand, which of course failed.
8358 (define_insn "andqi_ext_0"
8359   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8360                          (const_int 8)
8361                          (const_int 8))
8362         (and:SI 
8363           (zero_extract:SI
8364             (match_operand 1 "ext_register_operand" "0")
8365             (const_int 8)
8366             (const_int 8))
8367           (match_operand 2 "const_int_operand" "n")))
8368    (clobber (reg:CC FLAGS_REG))]
8369   ""
8370   "and{b}\t{%2, %h0|%h0, %2}"
8371   [(set_attr "type" "alu")
8372    (set_attr "length_immediate" "1")
8373    (set_attr "mode" "QI")])
8375 ;; Generated by peephole translating test to and.  This shows up
8376 ;; often in fp comparisons.
8378 (define_insn "*andqi_ext_0_cc"
8379   [(set (reg FLAGS_REG)
8380         (compare
8381           (and:SI
8382             (zero_extract:SI
8383               (match_operand 1 "ext_register_operand" "0")
8384               (const_int 8)
8385               (const_int 8))
8386             (match_operand 2 "const_int_operand" "n"))
8387           (const_int 0)))
8388    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8389                          (const_int 8)
8390                          (const_int 8))
8391         (and:SI 
8392           (zero_extract:SI
8393             (match_dup 1)
8394             (const_int 8)
8395             (const_int 8))
8396           (match_dup 2)))]
8397   "ix86_match_ccmode (insn, CCNOmode)"
8398   "and{b}\t{%2, %h0|%h0, %2}"
8399   [(set_attr "type" "alu")
8400    (set_attr "length_immediate" "1")
8401    (set_attr "mode" "QI")])
8403 (define_insn "*andqi_ext_1"
8404   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8405                          (const_int 8)
8406                          (const_int 8))
8407         (and:SI 
8408           (zero_extract:SI
8409             (match_operand 1 "ext_register_operand" "0")
8410             (const_int 8)
8411             (const_int 8))
8412           (zero_extend:SI
8413             (match_operand:QI 2 "general_operand" "Qm"))))
8414    (clobber (reg:CC FLAGS_REG))]
8415   "!TARGET_64BIT"
8416   "and{b}\t{%2, %h0|%h0, %2}"
8417   [(set_attr "type" "alu")
8418    (set_attr "length_immediate" "0")
8419    (set_attr "mode" "QI")])
8421 (define_insn "*andqi_ext_1_rex64"
8422   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8423                          (const_int 8)
8424                          (const_int 8))
8425         (and:SI 
8426           (zero_extract:SI
8427             (match_operand 1 "ext_register_operand" "0")
8428             (const_int 8)
8429             (const_int 8))
8430           (zero_extend:SI
8431             (match_operand 2 "ext_register_operand" "Q"))))
8432    (clobber (reg:CC FLAGS_REG))]
8433   "TARGET_64BIT"
8434   "and{b}\t{%2, %h0|%h0, %2}"
8435   [(set_attr "type" "alu")
8436    (set_attr "length_immediate" "0")
8437    (set_attr "mode" "QI")])
8439 (define_insn "*andqi_ext_2"
8440   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8441                          (const_int 8)
8442                          (const_int 8))
8443         (and:SI
8444           (zero_extract:SI
8445             (match_operand 1 "ext_register_operand" "%0")
8446             (const_int 8)
8447             (const_int 8))
8448           (zero_extract:SI
8449             (match_operand 2 "ext_register_operand" "Q")
8450             (const_int 8)
8451             (const_int 8))))
8452    (clobber (reg:CC FLAGS_REG))]
8453   ""
8454   "and{b}\t{%h2, %h0|%h0, %h2}"
8455   [(set_attr "type" "alu")
8456    (set_attr "length_immediate" "0")
8457    (set_attr "mode" "QI")])
8459 ;; Convert wide AND instructions with immediate operand to shorter QImode
8460 ;; equivalents when possible.
8461 ;; Don't do the splitting with memory operands, since it introduces risk
8462 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8463 ;; for size, but that can (should?) be handled by generic code instead.
8464 (define_split
8465   [(set (match_operand 0 "register_operand" "")
8466         (and (match_operand 1 "register_operand" "")
8467              (match_operand 2 "const_int_operand" "")))
8468    (clobber (reg:CC FLAGS_REG))]
8469    "reload_completed
8470     && QI_REG_P (operands[0])
8471     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8472     && !(~INTVAL (operands[2]) & ~(255 << 8))
8473     && GET_MODE (operands[0]) != QImode"
8474   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8475                    (and:SI (zero_extract:SI (match_dup 1)
8476                                             (const_int 8) (const_int 8))
8477                            (match_dup 2)))
8478               (clobber (reg:CC FLAGS_REG))])]
8479   "operands[0] = gen_lowpart (SImode, operands[0]);
8480    operands[1] = gen_lowpart (SImode, operands[1]);
8481    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8483 ;; Since AND can be encoded with sign extended immediate, this is only
8484 ;; profitable when 7th bit is not set.
8485 (define_split
8486   [(set (match_operand 0 "register_operand" "")
8487         (and (match_operand 1 "general_operand" "")
8488              (match_operand 2 "const_int_operand" "")))
8489    (clobber (reg:CC FLAGS_REG))]
8490    "reload_completed
8491     && ANY_QI_REG_P (operands[0])
8492     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8493     && !(~INTVAL (operands[2]) & ~255)
8494     && !(INTVAL (operands[2]) & 128)
8495     && GET_MODE (operands[0]) != QImode"
8496   [(parallel [(set (strict_low_part (match_dup 0))
8497                    (and:QI (match_dup 1)
8498                            (match_dup 2)))
8499               (clobber (reg:CC FLAGS_REG))])]
8500   "operands[0] = gen_lowpart (QImode, operands[0]);
8501    operands[1] = gen_lowpart (QImode, operands[1]);
8502    operands[2] = gen_lowpart (QImode, operands[2]);")
8504 ;; Logical inclusive OR instructions
8506 ;; %%% This used to optimize known byte-wide and operations to memory.
8507 ;; If this is considered useful, it should be done with splitters.
8509 (define_expand "iordi3"
8510   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8511         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8512                 (match_operand:DI 2 "x86_64_general_operand" "")))
8513    (clobber (reg:CC FLAGS_REG))]
8514   "TARGET_64BIT"
8515   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8517 (define_insn "*iordi_1_rex64"
8518   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8519         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8520                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8521    (clobber (reg:CC FLAGS_REG))]
8522   "TARGET_64BIT
8523    && ix86_binary_operator_ok (IOR, DImode, operands)"
8524   "or{q}\t{%2, %0|%0, %2}"
8525   [(set_attr "type" "alu")
8526    (set_attr "mode" "DI")])
8528 (define_insn "*iordi_2_rex64"
8529   [(set (reg FLAGS_REG)
8530         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8531                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8532                  (const_int 0)))
8533    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8534         (ior:DI (match_dup 1) (match_dup 2)))]
8535   "TARGET_64BIT
8536    && ix86_match_ccmode (insn, CCNOmode)
8537    && ix86_binary_operator_ok (IOR, DImode, operands)"
8538   "or{q}\t{%2, %0|%0, %2}"
8539   [(set_attr "type" "alu")
8540    (set_attr "mode" "DI")])
8542 (define_insn "*iordi_3_rex64"
8543   [(set (reg FLAGS_REG)
8544         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8545                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8546                  (const_int 0)))
8547    (clobber (match_scratch:DI 0 "=r"))]
8548   "TARGET_64BIT
8549    && ix86_match_ccmode (insn, CCNOmode)
8550    && ix86_binary_operator_ok (IOR, DImode, operands)"
8551   "or{q}\t{%2, %0|%0, %2}"
8552   [(set_attr "type" "alu")
8553    (set_attr "mode" "DI")])
8556 (define_expand "iorsi3"
8557   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8558         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8559                 (match_operand:SI 2 "general_operand" "")))
8560    (clobber (reg:CC FLAGS_REG))]
8561   ""
8562   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8564 (define_insn "*iorsi_1"
8565   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8566         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8567                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "ix86_binary_operator_ok (IOR, SImode, operands)"
8570   "or{l}\t{%2, %0|%0, %2}"
8571   [(set_attr "type" "alu")
8572    (set_attr "mode" "SI")])
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 (define_insn "*iorsi_1_zext"
8576   [(set (match_operand:DI 0 "register_operand" "=rm")
8577         (zero_extend:DI
8578           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579                   (match_operand:SI 2 "general_operand" "rim"))))
8580    (clobber (reg:CC FLAGS_REG))]
8581   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8582   "or{l}\t{%2, %k0|%k0, %2}"
8583   [(set_attr "type" "alu")
8584    (set_attr "mode" "SI")])
8586 (define_insn "*iorsi_1_zext_imm"
8587   [(set (match_operand:DI 0 "register_operand" "=rm")
8588         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8589                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8590    (clobber (reg:CC FLAGS_REG))]
8591   "TARGET_64BIT"
8592   "or{l}\t{%2, %k0|%k0, %2}"
8593   [(set_attr "type" "alu")
8594    (set_attr "mode" "SI")])
8596 (define_insn "*iorsi_2"
8597   [(set (reg FLAGS_REG)
8598         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8599                          (match_operand:SI 2 "general_operand" "rim,ri"))
8600                  (const_int 0)))
8601    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8602         (ior:SI (match_dup 1) (match_dup 2)))]
8603   "ix86_match_ccmode (insn, CCNOmode)
8604    && ix86_binary_operator_ok (IOR, SImode, operands)"
8605   "or{l}\t{%2, %0|%0, %2}"
8606   [(set_attr "type" "alu")
8607    (set_attr "mode" "SI")])
8609 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8610 ;; ??? Special case for immediate operand is missing - it is tricky.
8611 (define_insn "*iorsi_2_zext"
8612   [(set (reg FLAGS_REG)
8613         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8614                          (match_operand:SI 2 "general_operand" "rim"))
8615                  (const_int 0)))
8616    (set (match_operand:DI 0 "register_operand" "=r")
8617         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8618   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8619    && ix86_binary_operator_ok (IOR, SImode, operands)"
8620   "or{l}\t{%2, %k0|%k0, %2}"
8621   [(set_attr "type" "alu")
8622    (set_attr "mode" "SI")])
8624 (define_insn "*iorsi_2_zext_imm"
8625   [(set (reg FLAGS_REG)
8626         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8627                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8628                  (const_int 0)))
8629    (set (match_operand:DI 0 "register_operand" "=r")
8630         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8631   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8632    && ix86_binary_operator_ok (IOR, SImode, operands)"
8633   "or{l}\t{%2, %k0|%k0, %2}"
8634   [(set_attr "type" "alu")
8635    (set_attr "mode" "SI")])
8637 (define_insn "*iorsi_3"
8638   [(set (reg FLAGS_REG)
8639         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8640                          (match_operand:SI 2 "general_operand" "rim"))
8641                  (const_int 0)))
8642    (clobber (match_scratch:SI 0 "=r"))]
8643   "ix86_match_ccmode (insn, CCNOmode)
8644    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8645   "or{l}\t{%2, %0|%0, %2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "mode" "SI")])
8649 (define_expand "iorhi3"
8650   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8651         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8652                 (match_operand:HI 2 "general_operand" "")))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "TARGET_HIMODE_MATH"
8655   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8657 (define_insn "*iorhi_1"
8658   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8659         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8660                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8661    (clobber (reg:CC FLAGS_REG))]
8662   "ix86_binary_operator_ok (IOR, HImode, operands)"
8663   "or{w}\t{%2, %0|%0, %2}"
8664   [(set_attr "type" "alu")
8665    (set_attr "mode" "HI")])
8667 (define_insn "*iorhi_2"
8668   [(set (reg FLAGS_REG)
8669         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8670                          (match_operand:HI 2 "general_operand" "rim,ri"))
8671                  (const_int 0)))
8672    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8673         (ior:HI (match_dup 1) (match_dup 2)))]
8674   "ix86_match_ccmode (insn, CCNOmode)
8675    && ix86_binary_operator_ok (IOR, HImode, operands)"
8676   "or{w}\t{%2, %0|%0, %2}"
8677   [(set_attr "type" "alu")
8678    (set_attr "mode" "HI")])
8680 (define_insn "*iorhi_3"
8681   [(set (reg FLAGS_REG)
8682         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8683                          (match_operand:HI 2 "general_operand" "rim"))
8684                  (const_int 0)))
8685    (clobber (match_scratch:HI 0 "=r"))]
8686   "ix86_match_ccmode (insn, CCNOmode)
8687    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8688   "or{w}\t{%2, %0|%0, %2}"
8689   [(set_attr "type" "alu")
8690    (set_attr "mode" "HI")])
8692 (define_expand "iorqi3"
8693   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8694         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8695                 (match_operand:QI 2 "general_operand" "")))
8696    (clobber (reg:CC FLAGS_REG))]
8697   "TARGET_QIMODE_MATH"
8698   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8700 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8701 (define_insn "*iorqi_1"
8702   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8703         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8704                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8705    (clobber (reg:CC FLAGS_REG))]
8706   "ix86_binary_operator_ok (IOR, QImode, operands)"
8707   "@
8708    or{b}\t{%2, %0|%0, %2}
8709    or{b}\t{%2, %0|%0, %2}
8710    or{l}\t{%k2, %k0|%k0, %k2}"
8711   [(set_attr "type" "alu")
8712    (set_attr "mode" "QI,QI,SI")])
8714 (define_insn "*iorqi_1_slp"
8715   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8716         (ior:QI (match_dup 0)
8717                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8718    (clobber (reg:CC FLAGS_REG))]
8719   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8720    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8721   "or{b}\t{%1, %0|%0, %1}"
8722   [(set_attr "type" "alu1")
8723    (set_attr "mode" "QI")])
8725 (define_insn "*iorqi_2"
8726   [(set (reg FLAGS_REG)
8727         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8728                          (match_operand:QI 2 "general_operand" "qim,qi"))
8729                  (const_int 0)))
8730    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8731         (ior:QI (match_dup 1) (match_dup 2)))]
8732   "ix86_match_ccmode (insn, CCNOmode)
8733    && ix86_binary_operator_ok (IOR, QImode, operands)"
8734   "or{b}\t{%2, %0|%0, %2}"
8735   [(set_attr "type" "alu")
8736    (set_attr "mode" "QI")])
8738 (define_insn "*iorqi_2_slp"
8739   [(set (reg FLAGS_REG)
8740         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8741                          (match_operand:QI 1 "general_operand" "qim,qi"))
8742                  (const_int 0)))
8743    (set (strict_low_part (match_dup 0))
8744         (ior:QI (match_dup 0) (match_dup 1)))]
8745   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8746    && ix86_match_ccmode (insn, CCNOmode)
8747    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8748   "or{b}\t{%1, %0|%0, %1}"
8749   [(set_attr "type" "alu1")
8750    (set_attr "mode" "QI")])
8752 (define_insn "*iorqi_3"
8753   [(set (reg FLAGS_REG)
8754         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8755                          (match_operand:QI 2 "general_operand" "qim"))
8756                  (const_int 0)))
8757    (clobber (match_scratch:QI 0 "=q"))]
8758   "ix86_match_ccmode (insn, CCNOmode)
8759    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8760   "or{b}\t{%2, %0|%0, %2}"
8761   [(set_attr "type" "alu")
8762    (set_attr "mode" "QI")])
8764 (define_insn "iorqi_ext_0"
8765   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8766                          (const_int 8)
8767                          (const_int 8))
8768         (ior:SI 
8769           (zero_extract:SI
8770             (match_operand 1 "ext_register_operand" "0")
8771             (const_int 8)
8772             (const_int 8))
8773           (match_operand 2 "const_int_operand" "n")))
8774    (clobber (reg:CC FLAGS_REG))]
8775   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8776   "or{b}\t{%2, %h0|%h0, %2}"
8777   [(set_attr "type" "alu")
8778    (set_attr "length_immediate" "1")
8779    (set_attr "mode" "QI")])
8781 (define_insn "*iorqi_ext_1"
8782   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8783                          (const_int 8)
8784                          (const_int 8))
8785         (ior:SI 
8786           (zero_extract:SI
8787             (match_operand 1 "ext_register_operand" "0")
8788             (const_int 8)
8789             (const_int 8))
8790           (zero_extend:SI
8791             (match_operand:QI 2 "general_operand" "Qm"))))
8792    (clobber (reg:CC FLAGS_REG))]
8793   "!TARGET_64BIT
8794    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8795   "or{b}\t{%2, %h0|%h0, %2}"
8796   [(set_attr "type" "alu")
8797    (set_attr "length_immediate" "0")
8798    (set_attr "mode" "QI")])
8800 (define_insn "*iorqi_ext_1_rex64"
8801   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8802                          (const_int 8)
8803                          (const_int 8))
8804         (ior:SI 
8805           (zero_extract:SI
8806             (match_operand 1 "ext_register_operand" "0")
8807             (const_int 8)
8808             (const_int 8))
8809           (zero_extend:SI
8810             (match_operand 2 "ext_register_operand" "Q"))))
8811    (clobber (reg:CC FLAGS_REG))]
8812   "TARGET_64BIT
8813    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8814   "or{b}\t{%2, %h0|%h0, %2}"
8815   [(set_attr "type" "alu")
8816    (set_attr "length_immediate" "0")
8817    (set_attr "mode" "QI")])
8819 (define_insn "*iorqi_ext_2"
8820   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821                          (const_int 8)
8822                          (const_int 8))
8823         (ior:SI 
8824           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8825                            (const_int 8)
8826                            (const_int 8))
8827           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8828                            (const_int 8)
8829                            (const_int 8))))
8830    (clobber (reg:CC FLAGS_REG))]
8831   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8832   "ior{b}\t{%h2, %h0|%h0, %h2}"
8833   [(set_attr "type" "alu")
8834    (set_attr "length_immediate" "0")
8835    (set_attr "mode" "QI")])
8837 (define_split
8838   [(set (match_operand 0 "register_operand" "")
8839         (ior (match_operand 1 "register_operand" "")
8840              (match_operand 2 "const_int_operand" "")))
8841    (clobber (reg:CC FLAGS_REG))]
8842    "reload_completed
8843     && QI_REG_P (operands[0])
8844     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8845     && !(INTVAL (operands[2]) & ~(255 << 8))
8846     && GET_MODE (operands[0]) != QImode"
8847   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8848                    (ior:SI (zero_extract:SI (match_dup 1)
8849                                             (const_int 8) (const_int 8))
8850                            (match_dup 2)))
8851               (clobber (reg:CC FLAGS_REG))])]
8852   "operands[0] = gen_lowpart (SImode, operands[0]);
8853    operands[1] = gen_lowpart (SImode, operands[1]);
8854    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8856 ;; Since OR can be encoded with sign extended immediate, this is only
8857 ;; profitable when 7th bit is set.
8858 (define_split
8859   [(set (match_operand 0 "register_operand" "")
8860         (ior (match_operand 1 "general_operand" "")
8861              (match_operand 2 "const_int_operand" "")))
8862    (clobber (reg:CC FLAGS_REG))]
8863    "reload_completed
8864     && ANY_QI_REG_P (operands[0])
8865     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8866     && !(INTVAL (operands[2]) & ~255)
8867     && (INTVAL (operands[2]) & 128)
8868     && GET_MODE (operands[0]) != QImode"
8869   [(parallel [(set (strict_low_part (match_dup 0))
8870                    (ior:QI (match_dup 1)
8871                            (match_dup 2)))
8872               (clobber (reg:CC FLAGS_REG))])]
8873   "operands[0] = gen_lowpart (QImode, operands[0]);
8874    operands[1] = gen_lowpart (QImode, operands[1]);
8875    operands[2] = gen_lowpart (QImode, operands[2]);")
8877 ;; Logical XOR instructions
8879 ;; %%% This used to optimize known byte-wide and operations to memory.
8880 ;; If this is considered useful, it should be done with splitters.
8882 (define_expand "xordi3"
8883   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8884         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8885                 (match_operand:DI 2 "x86_64_general_operand" "")))
8886    (clobber (reg:CC FLAGS_REG))]
8887   "TARGET_64BIT"
8888   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8890 (define_insn "*xordi_1_rex64"
8891   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8892         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8893                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8894    (clobber (reg:CC FLAGS_REG))]
8895   "TARGET_64BIT
8896    && ix86_binary_operator_ok (XOR, DImode, operands)"
8897   "@
8898    xor{q}\t{%2, %0|%0, %2}
8899    xor{q}\t{%2, %0|%0, %2}"
8900   [(set_attr "type" "alu")
8901    (set_attr "mode" "DI,DI")])
8903 (define_insn "*xordi_2_rex64"
8904   [(set (reg FLAGS_REG)
8905         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8906                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8907                  (const_int 0)))
8908    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8909         (xor:DI (match_dup 1) (match_dup 2)))]
8910   "TARGET_64BIT
8911    && ix86_match_ccmode (insn, CCNOmode)
8912    && ix86_binary_operator_ok (XOR, DImode, operands)"
8913   "@
8914    xor{q}\t{%2, %0|%0, %2}
8915    xor{q}\t{%2, %0|%0, %2}"
8916   [(set_attr "type" "alu")
8917    (set_attr "mode" "DI,DI")])
8919 (define_insn "*xordi_3_rex64"
8920   [(set (reg FLAGS_REG)
8921         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8922                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8923                  (const_int 0)))
8924    (clobber (match_scratch:DI 0 "=r"))]
8925   "TARGET_64BIT
8926    && ix86_match_ccmode (insn, CCNOmode)
8927    && ix86_binary_operator_ok (XOR, DImode, operands)"
8928   "xor{q}\t{%2, %0|%0, %2}"
8929   [(set_attr "type" "alu")
8930    (set_attr "mode" "DI")])
8932 (define_expand "xorsi3"
8933   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8934         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8935                 (match_operand:SI 2 "general_operand" "")))
8936    (clobber (reg:CC FLAGS_REG))]
8937   ""
8938   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8940 (define_insn "*xorsi_1"
8941   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8942         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8943                 (match_operand:SI 2 "general_operand" "ri,rm")))
8944    (clobber (reg:CC FLAGS_REG))]
8945   "ix86_binary_operator_ok (XOR, SImode, operands)"
8946   "xor{l}\t{%2, %0|%0, %2}"
8947   [(set_attr "type" "alu")
8948    (set_attr "mode" "SI")])
8950 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8951 ;; Add speccase for immediates
8952 (define_insn "*xorsi_1_zext"
8953   [(set (match_operand:DI 0 "register_operand" "=r")
8954         (zero_extend:DI
8955           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956                   (match_operand:SI 2 "general_operand" "rim"))))
8957    (clobber (reg:CC FLAGS_REG))]
8958   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8959   "xor{l}\t{%2, %k0|%k0, %2}"
8960   [(set_attr "type" "alu")
8961    (set_attr "mode" "SI")])
8963 (define_insn "*xorsi_1_zext_imm"
8964   [(set (match_operand:DI 0 "register_operand" "=r")
8965         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8966                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8967    (clobber (reg:CC FLAGS_REG))]
8968   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8969   "xor{l}\t{%2, %k0|%k0, %2}"
8970   [(set_attr "type" "alu")
8971    (set_attr "mode" "SI")])
8973 (define_insn "*xorsi_2"
8974   [(set (reg FLAGS_REG)
8975         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8976                          (match_operand:SI 2 "general_operand" "rim,ri"))
8977                  (const_int 0)))
8978    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8979         (xor:SI (match_dup 1) (match_dup 2)))]
8980   "ix86_match_ccmode (insn, CCNOmode)
8981    && ix86_binary_operator_ok (XOR, SImode, operands)"
8982   "xor{l}\t{%2, %0|%0, %2}"
8983   [(set_attr "type" "alu")
8984    (set_attr "mode" "SI")])
8986 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8987 ;; ??? Special case for immediate operand is missing - it is tricky.
8988 (define_insn "*xorsi_2_zext"
8989   [(set (reg FLAGS_REG)
8990         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8991                          (match_operand:SI 2 "general_operand" "rim"))
8992                  (const_int 0)))
8993    (set (match_operand:DI 0 "register_operand" "=r")
8994         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8995   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8996    && ix86_binary_operator_ok (XOR, SImode, operands)"
8997   "xor{l}\t{%2, %k0|%k0, %2}"
8998   [(set_attr "type" "alu")
8999    (set_attr "mode" "SI")])
9001 (define_insn "*xorsi_2_zext_imm"
9002   [(set (reg FLAGS_REG)
9003         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9004                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9005                  (const_int 0)))
9006    (set (match_operand:DI 0 "register_operand" "=r")
9007         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9008   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9009    && ix86_binary_operator_ok (XOR, SImode, operands)"
9010   "xor{l}\t{%2, %k0|%k0, %2}"
9011   [(set_attr "type" "alu")
9012    (set_attr "mode" "SI")])
9014 (define_insn "*xorsi_3"
9015   [(set (reg FLAGS_REG)
9016         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9017                          (match_operand:SI 2 "general_operand" "rim"))
9018                  (const_int 0)))
9019    (clobber (match_scratch:SI 0 "=r"))]
9020   "ix86_match_ccmode (insn, CCNOmode)
9021    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9022   "xor{l}\t{%2, %0|%0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "SI")])
9026 (define_expand "xorhi3"
9027   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9028         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9029                 (match_operand:HI 2 "general_operand" "")))
9030    (clobber (reg:CC FLAGS_REG))]
9031   "TARGET_HIMODE_MATH"
9032   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9034 (define_insn "*xorhi_1"
9035   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9036         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9037                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9038    (clobber (reg:CC FLAGS_REG))]
9039   "ix86_binary_operator_ok (XOR, HImode, operands)"
9040   "xor{w}\t{%2, %0|%0, %2}"
9041   [(set_attr "type" "alu")
9042    (set_attr "mode" "HI")])
9044 (define_insn "*xorhi_2"
9045   [(set (reg FLAGS_REG)
9046         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9047                          (match_operand:HI 2 "general_operand" "rim,ri"))
9048                  (const_int 0)))
9049    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9050         (xor:HI (match_dup 1) (match_dup 2)))]
9051   "ix86_match_ccmode (insn, CCNOmode)
9052    && ix86_binary_operator_ok (XOR, HImode, operands)"
9053   "xor{w}\t{%2, %0|%0, %2}"
9054   [(set_attr "type" "alu")
9055    (set_attr "mode" "HI")])
9057 (define_insn "*xorhi_3"
9058   [(set (reg FLAGS_REG)
9059         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9060                          (match_operand:HI 2 "general_operand" "rim"))
9061                  (const_int 0)))
9062    (clobber (match_scratch:HI 0 "=r"))]
9063   "ix86_match_ccmode (insn, CCNOmode)
9064    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9065   "xor{w}\t{%2, %0|%0, %2}"
9066   [(set_attr "type" "alu")
9067    (set_attr "mode" "HI")])
9069 (define_expand "xorqi3"
9070   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9071         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9072                 (match_operand:QI 2 "general_operand" "")))
9073    (clobber (reg:CC FLAGS_REG))]
9074   "TARGET_QIMODE_MATH"
9075   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9077 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9078 (define_insn "*xorqi_1"
9079   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9080         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9081                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9082    (clobber (reg:CC FLAGS_REG))]
9083   "ix86_binary_operator_ok (XOR, QImode, operands)"
9084   "@
9085    xor{b}\t{%2, %0|%0, %2}
9086    xor{b}\t{%2, %0|%0, %2}
9087    xor{l}\t{%k2, %k0|%k0, %k2}"
9088   [(set_attr "type" "alu")
9089    (set_attr "mode" "QI,QI,SI")])
9091 (define_insn "*xorqi_1_slp"
9092   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9093         (xor:QI (match_dup 0)
9094                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9095    (clobber (reg:CC FLAGS_REG))]
9096   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9097    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9098   "xor{b}\t{%1, %0|%0, %1}"
9099   [(set_attr "type" "alu1")
9100    (set_attr "mode" "QI")])
9102 (define_insn "xorqi_ext_0"
9103   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9104                          (const_int 8)
9105                          (const_int 8))
9106         (xor:SI 
9107           (zero_extract:SI
9108             (match_operand 1 "ext_register_operand" "0")
9109             (const_int 8)
9110             (const_int 8))
9111           (match_operand 2 "const_int_operand" "n")))
9112    (clobber (reg:CC FLAGS_REG))]
9113   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9114   "xor{b}\t{%2, %h0|%h0, %2}"
9115   [(set_attr "type" "alu")
9116    (set_attr "length_immediate" "1")
9117    (set_attr "mode" "QI")])
9119 (define_insn "*xorqi_ext_1"
9120   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9121                          (const_int 8)
9122                          (const_int 8))
9123         (xor:SI 
9124           (zero_extract:SI
9125             (match_operand 1 "ext_register_operand" "0")
9126             (const_int 8)
9127             (const_int 8))
9128           (zero_extend:SI
9129             (match_operand:QI 2 "general_operand" "Qm"))))
9130    (clobber (reg:CC FLAGS_REG))]
9131   "!TARGET_64BIT
9132    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9133   "xor{b}\t{%2, %h0|%h0, %2}"
9134   [(set_attr "type" "alu")
9135    (set_attr "length_immediate" "0")
9136    (set_attr "mode" "QI")])
9138 (define_insn "*xorqi_ext_1_rex64"
9139   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9140                          (const_int 8)
9141                          (const_int 8))
9142         (xor:SI 
9143           (zero_extract:SI
9144             (match_operand 1 "ext_register_operand" "0")
9145             (const_int 8)
9146             (const_int 8))
9147           (zero_extend:SI
9148             (match_operand 2 "ext_register_operand" "Q"))))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "TARGET_64BIT
9151    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9152   "xor{b}\t{%2, %h0|%h0, %2}"
9153   [(set_attr "type" "alu")
9154    (set_attr "length_immediate" "0")
9155    (set_attr "mode" "QI")])
9157 (define_insn "*xorqi_ext_2"
9158   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159                          (const_int 8)
9160                          (const_int 8))
9161         (xor:SI 
9162           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9163                            (const_int 8)
9164                            (const_int 8))
9165           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9166                            (const_int 8)
9167                            (const_int 8))))
9168    (clobber (reg:CC FLAGS_REG))]
9169   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170   "xor{b}\t{%h2, %h0|%h0, %h2}"
9171   [(set_attr "type" "alu")
9172    (set_attr "length_immediate" "0")
9173    (set_attr "mode" "QI")])
9175 (define_insn "*xorqi_cc_1"
9176   [(set (reg FLAGS_REG)
9177         (compare
9178           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9179                   (match_operand:QI 2 "general_operand" "qim,qi"))
9180           (const_int 0)))
9181    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9182         (xor:QI (match_dup 1) (match_dup 2)))]
9183   "ix86_match_ccmode (insn, CCNOmode)
9184    && ix86_binary_operator_ok (XOR, QImode, operands)"
9185   "xor{b}\t{%2, %0|%0, %2}"
9186   [(set_attr "type" "alu")
9187    (set_attr "mode" "QI")])
9189 (define_insn "*xorqi_2_slp"
9190   [(set (reg FLAGS_REG)
9191         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9192                          (match_operand:QI 1 "general_operand" "qim,qi"))
9193                  (const_int 0)))
9194    (set (strict_low_part (match_dup 0))
9195         (xor:QI (match_dup 0) (match_dup 1)))]
9196   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9197    && ix86_match_ccmode (insn, CCNOmode)
9198    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9199   "xor{b}\t{%1, %0|%0, %1}"
9200   [(set_attr "type" "alu1")
9201    (set_attr "mode" "QI")])
9203 (define_insn "*xorqi_cc_2"
9204   [(set (reg FLAGS_REG)
9205         (compare
9206           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9207                   (match_operand:QI 2 "general_operand" "qim"))
9208           (const_int 0)))
9209    (clobber (match_scratch:QI 0 "=q"))]
9210   "ix86_match_ccmode (insn, CCNOmode)
9211    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9212   "xor{b}\t{%2, %0|%0, %2}"
9213   [(set_attr "type" "alu")
9214    (set_attr "mode" "QI")])
9216 (define_insn "*xorqi_cc_ext_1"
9217   [(set (reg FLAGS_REG)
9218         (compare
9219           (xor:SI
9220             (zero_extract:SI
9221               (match_operand 1 "ext_register_operand" "0")
9222               (const_int 8)
9223               (const_int 8))
9224             (match_operand:QI 2 "general_operand" "qmn"))
9225           (const_int 0)))
9226    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9227                          (const_int 8)
9228                          (const_int 8))
9229         (xor:SI 
9230           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9231           (match_dup 2)))]
9232   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9233   "xor{b}\t{%2, %h0|%h0, %2}"
9234   [(set_attr "type" "alu")
9235    (set_attr "mode" "QI")])
9237 (define_insn "*xorqi_cc_ext_1_rex64"
9238   [(set (reg FLAGS_REG)
9239         (compare
9240           (xor:SI
9241             (zero_extract:SI
9242               (match_operand 1 "ext_register_operand" "0")
9243               (const_int 8)
9244               (const_int 8))
9245             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9246           (const_int 0)))
9247    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9248                          (const_int 8)
9249                          (const_int 8))
9250         (xor:SI 
9251           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9252           (match_dup 2)))]
9253   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9254   "xor{b}\t{%2, %h0|%h0, %2}"
9255   [(set_attr "type" "alu")
9256    (set_attr "mode" "QI")])
9258 (define_expand "xorqi_cc_ext_1"
9259   [(parallel [
9260      (set (reg:CCNO FLAGS_REG)
9261           (compare:CCNO
9262             (xor:SI
9263               (zero_extract:SI
9264                 (match_operand 1 "ext_register_operand" "")
9265                 (const_int 8)
9266                 (const_int 8))
9267               (match_operand:QI 2 "general_operand" ""))
9268             (const_int 0)))
9269      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9270                            (const_int 8)
9271                            (const_int 8))
9272           (xor:SI 
9273             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9274             (match_dup 2)))])]
9275   ""
9276   "")
9278 (define_split
9279   [(set (match_operand 0 "register_operand" "")
9280         (xor (match_operand 1 "register_operand" "")
9281              (match_operand 2 "const_int_operand" "")))
9282    (clobber (reg:CC FLAGS_REG))]
9283    "reload_completed
9284     && QI_REG_P (operands[0])
9285     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9286     && !(INTVAL (operands[2]) & ~(255 << 8))
9287     && GET_MODE (operands[0]) != QImode"
9288   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9289                    (xor:SI (zero_extract:SI (match_dup 1)
9290                                             (const_int 8) (const_int 8))
9291                            (match_dup 2)))
9292               (clobber (reg:CC FLAGS_REG))])]
9293   "operands[0] = gen_lowpart (SImode, operands[0]);
9294    operands[1] = gen_lowpart (SImode, operands[1]);
9295    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9297 ;; Since XOR can be encoded with sign extended immediate, this is only
9298 ;; profitable when 7th bit is set.
9299 (define_split
9300   [(set (match_operand 0 "register_operand" "")
9301         (xor (match_operand 1 "general_operand" "")
9302              (match_operand 2 "const_int_operand" "")))
9303    (clobber (reg:CC FLAGS_REG))]
9304    "reload_completed
9305     && ANY_QI_REG_P (operands[0])
9306     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9307     && !(INTVAL (operands[2]) & ~255)
9308     && (INTVAL (operands[2]) & 128)
9309     && GET_MODE (operands[0]) != QImode"
9310   [(parallel [(set (strict_low_part (match_dup 0))
9311                    (xor:QI (match_dup 1)
9312                            (match_dup 2)))
9313               (clobber (reg:CC FLAGS_REG))])]
9314   "operands[0] = gen_lowpart (QImode, operands[0]);
9315    operands[1] = gen_lowpart (QImode, operands[1]);
9316    operands[2] = gen_lowpart (QImode, operands[2]);")
9318 ;; Negation instructions
9320 (define_expand "negti2"
9321   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9322                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9323               (clobber (reg:CC FLAGS_REG))])]
9324   "TARGET_64BIT"
9325   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9327 (define_insn "*negti2_1"
9328   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9329         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9330    (clobber (reg:CC FLAGS_REG))]
9331   "TARGET_64BIT
9332    && ix86_unary_operator_ok (NEG, TImode, operands)"
9333   "#")
9335 (define_split
9336   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9337         (neg:TI (match_operand:TI 1 "general_operand" "")))
9338    (clobber (reg:CC FLAGS_REG))]
9339   "TARGET_64BIT && reload_completed"
9340   [(parallel
9341     [(set (reg:CCZ FLAGS_REG)
9342           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9343      (set (match_dup 0) (neg:DI (match_dup 2)))])
9344    (parallel
9345     [(set (match_dup 1)
9346           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9347                             (match_dup 3))
9348                    (const_int 0)))
9349      (clobber (reg:CC FLAGS_REG))])
9350    (parallel
9351     [(set (match_dup 1)
9352           (neg:DI (match_dup 1)))
9353      (clobber (reg:CC FLAGS_REG))])]
9354   "split_ti (operands+1, 1, operands+2, operands+3);
9355    split_ti (operands+0, 1, operands+0, operands+1);")
9357 (define_expand "negdi2"
9358   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9359                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9360               (clobber (reg:CC FLAGS_REG))])]
9361   ""
9362   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9364 (define_insn "*negdi2_1"
9365   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9366         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9367    (clobber (reg:CC FLAGS_REG))]
9368   "!TARGET_64BIT
9369    && ix86_unary_operator_ok (NEG, DImode, operands)"
9370   "#")
9372 (define_split
9373   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9374         (neg:DI (match_operand:DI 1 "general_operand" "")))
9375    (clobber (reg:CC FLAGS_REG))]
9376   "!TARGET_64BIT && reload_completed"
9377   [(parallel
9378     [(set (reg:CCZ FLAGS_REG)
9379           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9380      (set (match_dup 0) (neg:SI (match_dup 2)))])
9381    (parallel
9382     [(set (match_dup 1)
9383           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9384                             (match_dup 3))
9385                    (const_int 0)))
9386      (clobber (reg:CC FLAGS_REG))])
9387    (parallel
9388     [(set (match_dup 1)
9389           (neg:SI (match_dup 1)))
9390      (clobber (reg:CC FLAGS_REG))])]
9391   "split_di (operands+1, 1, operands+2, operands+3);
9392    split_di (operands+0, 1, operands+0, operands+1);")
9394 (define_insn "*negdi2_1_rex64"
9395   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9396         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9397    (clobber (reg:CC FLAGS_REG))]
9398   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9399   "neg{q}\t%0"
9400   [(set_attr "type" "negnot")
9401    (set_attr "mode" "DI")])
9403 ;; The problem with neg is that it does not perform (compare x 0),
9404 ;; it really performs (compare 0 x), which leaves us with the zero
9405 ;; flag being the only useful item.
9407 (define_insn "*negdi2_cmpz_rex64"
9408   [(set (reg:CCZ FLAGS_REG)
9409         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9410                      (const_int 0)))
9411    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9412         (neg:DI (match_dup 1)))]
9413   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9414   "neg{q}\t%0"
9415   [(set_attr "type" "negnot")
9416    (set_attr "mode" "DI")])
9419 (define_expand "negsi2"
9420   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9421                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9422               (clobber (reg:CC FLAGS_REG))])]
9423   ""
9424   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9426 (define_insn "*negsi2_1"
9427   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9428         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9429    (clobber (reg:CC FLAGS_REG))]
9430   "ix86_unary_operator_ok (NEG, SImode, operands)"
9431   "neg{l}\t%0"
9432   [(set_attr "type" "negnot")
9433    (set_attr "mode" "SI")])
9435 ;; Combine is quite creative about this pattern.
9436 (define_insn "*negsi2_1_zext"
9437   [(set (match_operand:DI 0 "register_operand" "=r")
9438         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9439                                         (const_int 32)))
9440                      (const_int 32)))
9441    (clobber (reg:CC FLAGS_REG))]
9442   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9443   "neg{l}\t%k0"
9444   [(set_attr "type" "negnot")
9445    (set_attr "mode" "SI")])
9447 ;; The problem with neg is that it does not perform (compare x 0),
9448 ;; it really performs (compare 0 x), which leaves us with the zero
9449 ;; flag being the only useful item.
9451 (define_insn "*negsi2_cmpz"
9452   [(set (reg:CCZ FLAGS_REG)
9453         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9454                      (const_int 0)))
9455    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9456         (neg:SI (match_dup 1)))]
9457   "ix86_unary_operator_ok (NEG, SImode, operands)"
9458   "neg{l}\t%0"
9459   [(set_attr "type" "negnot")
9460    (set_attr "mode" "SI")])
9462 (define_insn "*negsi2_cmpz_zext"
9463   [(set (reg:CCZ FLAGS_REG)
9464         (compare:CCZ (lshiftrt:DI
9465                        (neg:DI (ashift:DI
9466                                  (match_operand:DI 1 "register_operand" "0")
9467                                  (const_int 32)))
9468                        (const_int 32))
9469                      (const_int 0)))
9470    (set (match_operand:DI 0 "register_operand" "=r")
9471         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9472                                         (const_int 32)))
9473                      (const_int 32)))]
9474   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9475   "neg{l}\t%k0"
9476   [(set_attr "type" "negnot")
9477    (set_attr "mode" "SI")])
9479 (define_expand "neghi2"
9480   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9481                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9482               (clobber (reg:CC FLAGS_REG))])]
9483   "TARGET_HIMODE_MATH"
9484   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9486 (define_insn "*neghi2_1"
9487   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9488         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9489    (clobber (reg:CC FLAGS_REG))]
9490   "ix86_unary_operator_ok (NEG, HImode, operands)"
9491   "neg{w}\t%0"
9492   [(set_attr "type" "negnot")
9493    (set_attr "mode" "HI")])
9495 (define_insn "*neghi2_cmpz"
9496   [(set (reg:CCZ FLAGS_REG)
9497         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9498                      (const_int 0)))
9499    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9500         (neg:HI (match_dup 1)))]
9501   "ix86_unary_operator_ok (NEG, HImode, operands)"
9502   "neg{w}\t%0"
9503   [(set_attr "type" "negnot")
9504    (set_attr "mode" "HI")])
9506 (define_expand "negqi2"
9507   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9508                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9509               (clobber (reg:CC FLAGS_REG))])]
9510   "TARGET_QIMODE_MATH"
9511   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9513 (define_insn "*negqi2_1"
9514   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9515         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9516    (clobber (reg:CC FLAGS_REG))]
9517   "ix86_unary_operator_ok (NEG, QImode, operands)"
9518   "neg{b}\t%0"
9519   [(set_attr "type" "negnot")
9520    (set_attr "mode" "QI")])
9522 (define_insn "*negqi2_cmpz"
9523   [(set (reg:CCZ FLAGS_REG)
9524         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9525                      (const_int 0)))
9526    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9527         (neg:QI (match_dup 1)))]
9528   "ix86_unary_operator_ok (NEG, QImode, operands)"
9529   "neg{b}\t%0"
9530   [(set_attr "type" "negnot")
9531    (set_attr "mode" "QI")])
9533 ;; Changing of sign for FP values is doable using integer unit too.
9535 (define_expand "negsf2"
9536   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9537         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9538   "TARGET_80387 || TARGET_SSE_MATH"
9539   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9541 (define_expand "abssf2"
9542   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9543         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9544   "TARGET_80387 || TARGET_SSE_MATH"
9545   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9547 (define_insn "*absnegsf2_mixed"
9548   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9549         (match_operator:SF 3 "absneg_operator"
9550           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9551    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9552    (clobber (reg:CC FLAGS_REG))]
9553   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9554    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9555   "#")
9557 (define_insn "*absnegsf2_sse"
9558   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9559         (match_operator:SF 3 "absneg_operator"
9560           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9561    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9562    (clobber (reg:CC FLAGS_REG))]
9563   "TARGET_SSE_MATH
9564    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9565   "#")
9567 (define_insn "*absnegsf2_i387"
9568   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9569         (match_operator:SF 3 "absneg_operator"
9570           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9571    (use (match_operand 2 "" ""))
9572    (clobber (reg:CC FLAGS_REG))]
9573   "TARGET_80387 && !TARGET_SSE_MATH
9574    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9575   "#")
9577 (define_expand "copysignsf3"
9578   [(match_operand:SF 0 "register_operand" "")
9579    (match_operand:SF 1 "nonmemory_operand" "")
9580    (match_operand:SF 2 "register_operand" "")]
9581   "TARGET_SSE_MATH"
9583   ix86_expand_copysign (operands);
9584   DONE;
9587 (define_insn_and_split "copysignsf3_const"
9588   [(set (match_operand:SF 0 "register_operand"          "=x")
9589         (unspec:SF
9590           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9591            (match_operand:SF 2 "register_operand"       "0")
9592            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9593           UNSPEC_COPYSIGN))]
9594   "TARGET_SSE_MATH"
9595   "#"
9596   "&& reload_completed"
9597   [(const_int 0)]
9599   ix86_split_copysign_const (operands);
9600   DONE;
9603 (define_insn "copysignsf3_var"
9604   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9605         (unspec:SF
9606           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9607            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9608            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9609            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9610           UNSPEC_COPYSIGN))
9611    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9612   "TARGET_SSE_MATH"
9613   "#")
9615 (define_split
9616   [(set (match_operand:SF 0 "register_operand" "")
9617         (unspec:SF
9618           [(match_operand:SF 2 "register_operand" "")
9619            (match_operand:SF 3 "register_operand" "")
9620            (match_operand:V4SF 4 "" "")
9621            (match_operand:V4SF 5 "" "")]
9622           UNSPEC_COPYSIGN))
9623    (clobber (match_scratch:V4SF 1 ""))]
9624   "TARGET_SSE_MATH && reload_completed"
9625   [(const_int 0)]
9627   ix86_split_copysign_var (operands);
9628   DONE;
9631 (define_expand "negdf2"
9632   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9633         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9634   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9635   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9637 (define_expand "absdf2"
9638   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9640   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9641   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9643 (define_insn "*absnegdf2_mixed"
9644   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9645         (match_operator:DF 3 "absneg_operator"
9646           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9647    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9648    (clobber (reg:CC FLAGS_REG))]
9649   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9650    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9651   "#")
9653 (define_insn "*absnegdf2_sse"
9654   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9655         (match_operator:DF 3 "absneg_operator"
9656           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9657    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9658    (clobber (reg:CC FLAGS_REG))]
9659   "TARGET_SSE2 && TARGET_SSE_MATH
9660    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9661   "#")
9663 (define_insn "*absnegdf2_i387"
9664   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9665         (match_operator:DF 3 "absneg_operator"
9666           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9667    (use (match_operand 2 "" ""))
9668    (clobber (reg:CC FLAGS_REG))]
9669   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9670    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9671   "#")
9673 (define_expand "copysigndf3"
9674   [(match_operand:DF 0 "register_operand" "")
9675    (match_operand:DF 1 "nonmemory_operand" "")
9676    (match_operand:DF 2 "register_operand" "")]
9677   "TARGET_SSE2 && TARGET_SSE_MATH"
9679   ix86_expand_copysign (operands);
9680   DONE;
9683 (define_insn_and_split "copysigndf3_const"
9684   [(set (match_operand:DF 0 "register_operand"          "=x")
9685         (unspec:DF
9686           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9687            (match_operand:DF 2 "register_operand"       "0")
9688            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9689           UNSPEC_COPYSIGN))]
9690   "TARGET_SSE2 && TARGET_SSE_MATH"
9691   "#"
9692   "&& reload_completed"
9693   [(const_int 0)]
9695   ix86_split_copysign_const (operands);
9696   DONE;
9699 (define_insn "copysigndf3_var"
9700   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9701         (unspec:DF
9702           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9703            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9704            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9705            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9706           UNSPEC_COPYSIGN))
9707    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9708   "TARGET_SSE2 && TARGET_SSE_MATH"
9709   "#")
9711 (define_split
9712   [(set (match_operand:DF 0 "register_operand" "")
9713         (unspec:DF
9714           [(match_operand:DF 2 "register_operand" "")
9715            (match_operand:DF 3 "register_operand" "")
9716            (match_operand:V2DF 4 "" "")
9717            (match_operand:V2DF 5 "" "")]
9718           UNSPEC_COPYSIGN))
9719    (clobber (match_scratch:V2DF 1 ""))]
9720   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9721   [(const_int 0)]
9723   ix86_split_copysign_var (operands);
9724   DONE;
9727 (define_expand "negxf2"
9728   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9729         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9730   "TARGET_80387"
9731   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9733 (define_expand "absxf2"
9734   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9735         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9736   "TARGET_80387"
9737   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9739 (define_insn "*absnegxf2_i387"
9740   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9741         (match_operator:XF 3 "absneg_operator"
9742           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9743    (use (match_operand 2 "" ""))
9744    (clobber (reg:CC FLAGS_REG))]
9745   "TARGET_80387
9746    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9747   "#")
9749 ;; Splitters for fp abs and neg.
9751 (define_split
9752   [(set (match_operand 0 "fp_register_operand" "")
9753         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9754    (use (match_operand 2 "" ""))
9755    (clobber (reg:CC FLAGS_REG))]
9756   "reload_completed"
9757   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9759 (define_split
9760   [(set (match_operand 0 "register_operand" "")
9761         (match_operator 3 "absneg_operator"
9762           [(match_operand 1 "register_operand" "")]))
9763    (use (match_operand 2 "nonimmediate_operand" ""))
9764    (clobber (reg:CC FLAGS_REG))]
9765   "reload_completed && SSE_REG_P (operands[0])"
9766   [(set (match_dup 0) (match_dup 3))]
9768   enum machine_mode mode = GET_MODE (operands[0]);
9769   enum machine_mode vmode = GET_MODE (operands[2]);
9770   rtx tmp;
9771   
9772   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9773   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9774   if (operands_match_p (operands[0], operands[2]))
9775     {
9776       tmp = operands[1];
9777       operands[1] = operands[2];
9778       operands[2] = tmp;
9779     }
9780   if (GET_CODE (operands[3]) == ABS)
9781     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9782   else
9783     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9784   operands[3] = tmp;
9787 (define_split
9788   [(set (match_operand:SF 0 "register_operand" "")
9789         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9790    (use (match_operand:V4SF 2 "" ""))
9791    (clobber (reg:CC FLAGS_REG))]
9792   "reload_completed"
9793   [(parallel [(set (match_dup 0) (match_dup 1))
9794               (clobber (reg:CC FLAGS_REG))])]
9796   rtx tmp;
9797   operands[0] = gen_lowpart (SImode, operands[0]);
9798   if (GET_CODE (operands[1]) == ABS)
9799     {
9800       tmp = gen_int_mode (0x7fffffff, SImode);
9801       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9802     }
9803   else
9804     {
9805       tmp = gen_int_mode (0x80000000, SImode);
9806       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9807     }
9808   operands[1] = tmp;
9811 (define_split
9812   [(set (match_operand:DF 0 "register_operand" "")
9813         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9814    (use (match_operand 2 "" ""))
9815    (clobber (reg:CC FLAGS_REG))]
9816   "reload_completed"
9817   [(parallel [(set (match_dup 0) (match_dup 1))
9818               (clobber (reg:CC FLAGS_REG))])]
9820   rtx tmp;
9821   if (TARGET_64BIT)
9822     {
9823       tmp = gen_lowpart (DImode, operands[0]);
9824       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9825       operands[0] = tmp;
9827       if (GET_CODE (operands[1]) == ABS)
9828         tmp = const0_rtx;
9829       else
9830         tmp = gen_rtx_NOT (DImode, tmp);
9831     }
9832   else
9833     {
9834       operands[0] = gen_highpart (SImode, operands[0]);
9835       if (GET_CODE (operands[1]) == ABS)
9836         {
9837           tmp = gen_int_mode (0x7fffffff, SImode);
9838           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9839         }
9840       else
9841         {
9842           tmp = gen_int_mode (0x80000000, SImode);
9843           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9844         }
9845     }
9846   operands[1] = tmp;
9849 (define_split
9850   [(set (match_operand:XF 0 "register_operand" "")
9851         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9852    (use (match_operand 2 "" ""))
9853    (clobber (reg:CC FLAGS_REG))]
9854   "reload_completed"
9855   [(parallel [(set (match_dup 0) (match_dup 1))
9856               (clobber (reg:CC FLAGS_REG))])]
9858   rtx tmp;
9859   operands[0] = gen_rtx_REG (SImode,
9860                              true_regnum (operands[0])
9861                              + (TARGET_64BIT ? 1 : 2));
9862   if (GET_CODE (operands[1]) == ABS)
9863     {
9864       tmp = GEN_INT (0x7fff);
9865       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9866     }
9867   else
9868     {
9869       tmp = GEN_INT (0x8000);
9870       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9871     }
9872   operands[1] = tmp;
9875 (define_split
9876   [(set (match_operand 0 "memory_operand" "")
9877         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9878    (use (match_operand 2 "" ""))
9879    (clobber (reg:CC FLAGS_REG))]
9880   "reload_completed"
9881   [(parallel [(set (match_dup 0) (match_dup 1))
9882               (clobber (reg:CC FLAGS_REG))])]
9884   enum machine_mode mode = GET_MODE (operands[0]);
9885   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9886   rtx tmp;
9888   operands[0] = adjust_address (operands[0], QImode, size - 1);
9889   if (GET_CODE (operands[1]) == ABS)
9890     {
9891       tmp = gen_int_mode (0x7f, QImode);
9892       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9893     }
9894   else
9895     {
9896       tmp = gen_int_mode (0x80, QImode);
9897       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9898     }
9899   operands[1] = tmp;
9902 ;; Conditionalize these after reload. If they match before reload, we 
9903 ;; lose the clobber and ability to use integer instructions.
9905 (define_insn "*negsf2_1"
9906   [(set (match_operand:SF 0 "register_operand" "=f")
9907         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9908   "TARGET_80387 && reload_completed"
9909   "fchs"
9910   [(set_attr "type" "fsgn")
9911    (set_attr "mode" "SF")])
9913 (define_insn "*negdf2_1"
9914   [(set (match_operand:DF 0 "register_operand" "=f")
9915         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9916   "TARGET_80387 && reload_completed"
9917   "fchs"
9918   [(set_attr "type" "fsgn")
9919    (set_attr "mode" "DF")])
9921 (define_insn "*negxf2_1"
9922   [(set (match_operand:XF 0 "register_operand" "=f")
9923         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9924   "TARGET_80387 && reload_completed"
9925   "fchs"
9926   [(set_attr "type" "fsgn")
9927    (set_attr "mode" "XF")])
9929 (define_insn "*abssf2_1"
9930   [(set (match_operand:SF 0 "register_operand" "=f")
9931         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9932   "TARGET_80387 && reload_completed"
9933   "fabs"
9934   [(set_attr "type" "fsgn")
9935    (set_attr "mode" "SF")])
9937 (define_insn "*absdf2_1"
9938   [(set (match_operand:DF 0 "register_operand" "=f")
9939         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9940   "TARGET_80387 && reload_completed"
9941   "fabs"
9942   [(set_attr "type" "fsgn")
9943    (set_attr "mode" "DF")])
9945 (define_insn "*absxf2_1"
9946   [(set (match_operand:XF 0 "register_operand" "=f")
9947         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9948   "TARGET_80387 && reload_completed"
9949   "fabs"
9950   [(set_attr "type" "fsgn")
9951    (set_attr "mode" "DF")])
9953 (define_insn "*negextendsfdf2"
9954   [(set (match_operand:DF 0 "register_operand" "=f")
9955         (neg:DF (float_extend:DF
9956                   (match_operand:SF 1 "register_operand" "0"))))]
9957   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9958   "fchs"
9959   [(set_attr "type" "fsgn")
9960    (set_attr "mode" "DF")])
9962 (define_insn "*negextenddfxf2"
9963   [(set (match_operand:XF 0 "register_operand" "=f")
9964         (neg:XF (float_extend:XF
9965                   (match_operand:DF 1 "register_operand" "0"))))]
9966   "TARGET_80387"
9967   "fchs"
9968   [(set_attr "type" "fsgn")
9969    (set_attr "mode" "XF")])
9971 (define_insn "*negextendsfxf2"
9972   [(set (match_operand:XF 0 "register_operand" "=f")
9973         (neg:XF (float_extend:XF
9974                   (match_operand:SF 1 "register_operand" "0"))))]
9975   "TARGET_80387"
9976   "fchs"
9977   [(set_attr "type" "fsgn")
9978    (set_attr "mode" "XF")])
9980 (define_insn "*absextendsfdf2"
9981   [(set (match_operand:DF 0 "register_operand" "=f")
9982         (abs:DF (float_extend:DF
9983                   (match_operand:SF 1 "register_operand" "0"))))]
9984   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9985   "fabs"
9986   [(set_attr "type" "fsgn")
9987    (set_attr "mode" "DF")])
9989 (define_insn "*absextenddfxf2"
9990   [(set (match_operand:XF 0 "register_operand" "=f")
9991         (abs:XF (float_extend:XF
9992           (match_operand:DF 1 "register_operand" "0"))))]
9993   "TARGET_80387"
9994   "fabs"
9995   [(set_attr "type" "fsgn")
9996    (set_attr "mode" "XF")])
9998 (define_insn "*absextendsfxf2"
9999   [(set (match_operand:XF 0 "register_operand" "=f")
10000         (abs:XF (float_extend:XF
10001           (match_operand:SF 1 "register_operand" "0"))))]
10002   "TARGET_80387"
10003   "fabs"
10004   [(set_attr "type" "fsgn")
10005    (set_attr "mode" "XF")])
10007 ;; One complement instructions
10009 (define_expand "one_cmpldi2"
10010   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10011         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10012   "TARGET_64BIT"
10013   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10015 (define_insn "*one_cmpldi2_1_rex64"
10016   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10017         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10018   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10019   "not{q}\t%0"
10020   [(set_attr "type" "negnot")
10021    (set_attr "mode" "DI")])
10023 (define_insn "*one_cmpldi2_2_rex64"
10024   [(set (reg FLAGS_REG)
10025         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10026                  (const_int 0)))
10027    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10028         (not:DI (match_dup 1)))]
10029   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10030    && ix86_unary_operator_ok (NOT, DImode, operands)"
10031   "#"
10032   [(set_attr "type" "alu1")
10033    (set_attr "mode" "DI")])
10035 (define_split
10036   [(set (match_operand 0 "flags_reg_operand" "")
10037         (match_operator 2 "compare_operator"
10038           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10039            (const_int 0)]))
10040    (set (match_operand:DI 1 "nonimmediate_operand" "")
10041         (not:DI (match_dup 3)))]
10042   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10043   [(parallel [(set (match_dup 0)
10044                    (match_op_dup 2
10045                      [(xor:DI (match_dup 3) (const_int -1))
10046                       (const_int 0)]))
10047               (set (match_dup 1)
10048                    (xor:DI (match_dup 3) (const_int -1)))])]
10049   "")
10051 (define_expand "one_cmplsi2"
10052   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10053         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10054   ""
10055   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10057 (define_insn "*one_cmplsi2_1"
10058   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10059         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10060   "ix86_unary_operator_ok (NOT, SImode, operands)"
10061   "not{l}\t%0"
10062   [(set_attr "type" "negnot")
10063    (set_attr "mode" "SI")])
10065 ;; ??? Currently never generated - xor is used instead.
10066 (define_insn "*one_cmplsi2_1_zext"
10067   [(set (match_operand:DI 0 "register_operand" "=r")
10068         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10069   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10070   "not{l}\t%k0"
10071   [(set_attr "type" "negnot")
10072    (set_attr "mode" "SI")])
10074 (define_insn "*one_cmplsi2_2"
10075   [(set (reg FLAGS_REG)
10076         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10077                  (const_int 0)))
10078    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10079         (not:SI (match_dup 1)))]
10080   "ix86_match_ccmode (insn, CCNOmode)
10081    && ix86_unary_operator_ok (NOT, SImode, operands)"
10082   "#"
10083   [(set_attr "type" "alu1")
10084    (set_attr "mode" "SI")])
10086 (define_split
10087   [(set (match_operand 0 "flags_reg_operand" "")
10088         (match_operator 2 "compare_operator"
10089           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10090            (const_int 0)]))
10091    (set (match_operand:SI 1 "nonimmediate_operand" "")
10092         (not:SI (match_dup 3)))]
10093   "ix86_match_ccmode (insn, CCNOmode)"
10094   [(parallel [(set (match_dup 0)
10095                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10096                                     (const_int 0)]))
10097               (set (match_dup 1)
10098                    (xor:SI (match_dup 3) (const_int -1)))])]
10099   "")
10101 ;; ??? Currently never generated - xor is used instead.
10102 (define_insn "*one_cmplsi2_2_zext"
10103   [(set (reg FLAGS_REG)
10104         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10105                  (const_int 0)))
10106    (set (match_operand:DI 0 "register_operand" "=r")
10107         (zero_extend:DI (not:SI (match_dup 1))))]
10108   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10109    && ix86_unary_operator_ok (NOT, SImode, operands)"
10110   "#"
10111   [(set_attr "type" "alu1")
10112    (set_attr "mode" "SI")])
10114 (define_split
10115   [(set (match_operand 0 "flags_reg_operand" "")
10116         (match_operator 2 "compare_operator"
10117           [(not:SI (match_operand:SI 3 "register_operand" ""))
10118            (const_int 0)]))
10119    (set (match_operand:DI 1 "register_operand" "")
10120         (zero_extend:DI (not:SI (match_dup 3))))]
10121   "ix86_match_ccmode (insn, CCNOmode)"
10122   [(parallel [(set (match_dup 0)
10123                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10124                                     (const_int 0)]))
10125               (set (match_dup 1)
10126                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10127   "")
10129 (define_expand "one_cmplhi2"
10130   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10131         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10132   "TARGET_HIMODE_MATH"
10133   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10135 (define_insn "*one_cmplhi2_1"
10136   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10137         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10138   "ix86_unary_operator_ok (NOT, HImode, operands)"
10139   "not{w}\t%0"
10140   [(set_attr "type" "negnot")
10141    (set_attr "mode" "HI")])
10143 (define_insn "*one_cmplhi2_2"
10144   [(set (reg FLAGS_REG)
10145         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10146                  (const_int 0)))
10147    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10148         (not:HI (match_dup 1)))]
10149   "ix86_match_ccmode (insn, CCNOmode)
10150    && ix86_unary_operator_ok (NEG, HImode, operands)"
10151   "#"
10152   [(set_attr "type" "alu1")
10153    (set_attr "mode" "HI")])
10155 (define_split
10156   [(set (match_operand 0 "flags_reg_operand" "")
10157         (match_operator 2 "compare_operator"
10158           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10159            (const_int 0)]))
10160    (set (match_operand:HI 1 "nonimmediate_operand" "")
10161         (not:HI (match_dup 3)))]
10162   "ix86_match_ccmode (insn, CCNOmode)"
10163   [(parallel [(set (match_dup 0)
10164                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10165                                     (const_int 0)]))
10166               (set (match_dup 1)
10167                    (xor:HI (match_dup 3) (const_int -1)))])]
10168   "")
10170 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10171 (define_expand "one_cmplqi2"
10172   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10173         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10174   "TARGET_QIMODE_MATH"
10175   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10177 (define_insn "*one_cmplqi2_1"
10178   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10179         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10180   "ix86_unary_operator_ok (NOT, QImode, operands)"
10181   "@
10182    not{b}\t%0
10183    not{l}\t%k0"
10184   [(set_attr "type" "negnot")
10185    (set_attr "mode" "QI,SI")])
10187 (define_insn "*one_cmplqi2_2"
10188   [(set (reg FLAGS_REG)
10189         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10190                  (const_int 0)))
10191    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10192         (not:QI (match_dup 1)))]
10193   "ix86_match_ccmode (insn, CCNOmode)
10194    && ix86_unary_operator_ok (NOT, QImode, operands)"
10195   "#"
10196   [(set_attr "type" "alu1")
10197    (set_attr "mode" "QI")])
10199 (define_split
10200   [(set (match_operand 0 "flags_reg_operand" "")
10201         (match_operator 2 "compare_operator"
10202           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10203            (const_int 0)]))
10204    (set (match_operand:QI 1 "nonimmediate_operand" "")
10205         (not:QI (match_dup 3)))]
10206   "ix86_match_ccmode (insn, CCNOmode)"
10207   [(parallel [(set (match_dup 0)
10208                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10209                                     (const_int 0)]))
10210               (set (match_dup 1)
10211                    (xor:QI (match_dup 3) (const_int -1)))])]
10212   "")
10214 ;; Arithmetic shift instructions
10216 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10217 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10218 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10219 ;; from the assembler input.
10221 ;; This instruction shifts the target reg/mem as usual, but instead of
10222 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10223 ;; is a left shift double, bits are taken from the high order bits of
10224 ;; reg, else if the insn is a shift right double, bits are taken from the
10225 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10226 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10228 ;; Since sh[lr]d does not change the `reg' operand, that is done
10229 ;; separately, making all shifts emit pairs of shift double and normal
10230 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10231 ;; support a 63 bit shift, each shift where the count is in a reg expands
10232 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10234 ;; If the shift count is a constant, we need never emit more than one
10235 ;; shift pair, instead using moves and sign extension for counts greater
10236 ;; than 31.
10238 (define_expand "ashlti3"
10239   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10240                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10241                               (match_operand:QI 2 "nonmemory_operand" "")))
10242               (clobber (reg:CC FLAGS_REG))])]
10243   "TARGET_64BIT"
10245   if (! immediate_operand (operands[2], QImode))
10246     {
10247       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10248       DONE;
10249     }
10250   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10251   DONE;
10254 (define_insn "ashlti3_1"
10255   [(set (match_operand:TI 0 "register_operand" "=r")
10256         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10257                    (match_operand:QI 2 "register_operand" "c")))
10258    (clobber (match_scratch:DI 3 "=&r"))
10259    (clobber (reg:CC FLAGS_REG))]
10260   "TARGET_64BIT"
10261   "#"
10262   [(set_attr "type" "multi")])
10264 (define_insn "*ashlti3_2"
10265   [(set (match_operand:TI 0 "register_operand" "=r")
10266         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10267                    (match_operand:QI 2 "immediate_operand" "O")))
10268    (clobber (reg:CC FLAGS_REG))]
10269   "TARGET_64BIT"
10270   "#"
10271   [(set_attr "type" "multi")])
10273 (define_split
10274   [(set (match_operand:TI 0 "register_operand" "")
10275         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10276                    (match_operand:QI 2 "register_operand" "")))
10277    (clobber (match_scratch:DI 3 ""))
10278    (clobber (reg:CC FLAGS_REG))]
10279   "TARGET_64BIT && reload_completed"
10280   [(const_int 0)]
10281   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10283 (define_split
10284   [(set (match_operand:TI 0 "register_operand" "")
10285         (ashift:TI (match_operand:TI 1 "register_operand" "")
10286                    (match_operand:QI 2 "immediate_operand" "")))
10287    (clobber (reg:CC FLAGS_REG))]
10288   "TARGET_64BIT && reload_completed"
10289   [(const_int 0)]
10290   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10292 (define_insn "x86_64_shld"
10293   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10294         (ior:DI (ashift:DI (match_dup 0)
10295                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10296                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10297                   (minus:QI (const_int 64) (match_dup 2)))))
10298    (clobber (reg:CC FLAGS_REG))]
10299   "TARGET_64BIT"
10300   "@
10301    shld{q}\t{%2, %1, %0|%0, %1, %2}
10302    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10303   [(set_attr "type" "ishift")
10304    (set_attr "prefix_0f" "1")
10305    (set_attr "mode" "DI")
10306    (set_attr "athlon_decode" "vector")])
10308 (define_expand "x86_64_shift_adj"
10309   [(set (reg:CCZ FLAGS_REG)
10310         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10311                              (const_int 64))
10312                      (const_int 0)))
10313    (set (match_operand:DI 0 "register_operand" "")
10314         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10315                          (match_operand:DI 1 "register_operand" "")
10316                          (match_dup 0)))
10317    (set (match_dup 1)
10318         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10319                          (match_operand:DI 3 "register_operand" "r")
10320                          (match_dup 1)))]
10321   "TARGET_64BIT"
10322   "")
10324 (define_expand "ashldi3"
10325   [(set (match_operand:DI 0 "shiftdi_operand" "")
10326         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10327                    (match_operand:QI 2 "nonmemory_operand" "")))]
10328   ""
10329   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10331 (define_insn "*ashldi3_1_rex64"
10332   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10333         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10334                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10335    (clobber (reg:CC FLAGS_REG))]
10336   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10338   switch (get_attr_type (insn))
10339     {
10340     case TYPE_ALU:
10341       gcc_assert (operands[2] == const1_rtx);
10342       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10343       return "add{q}\t{%0, %0|%0, %0}";
10345     case TYPE_LEA:
10346       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10347       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10348       operands[1] = gen_rtx_MULT (DImode, operands[1],
10349                                   GEN_INT (1 << INTVAL (operands[2])));
10350       return "lea{q}\t{%a1, %0|%0, %a1}";
10352     default:
10353       if (REG_P (operands[2]))
10354         return "sal{q}\t{%b2, %0|%0, %b2}";
10355       else if (operands[2] == const1_rtx
10356                && (TARGET_SHIFT1 || optimize_size))
10357         return "sal{q}\t%0";
10358       else
10359         return "sal{q}\t{%2, %0|%0, %2}";
10360     }
10362   [(set (attr "type")
10363      (cond [(eq_attr "alternative" "1")
10364               (const_string "lea")
10365             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10366                           (const_int 0))
10367                       (match_operand 0 "register_operand" ""))
10368                  (match_operand 2 "const1_operand" ""))
10369               (const_string "alu")
10370            ]
10371            (const_string "ishift")))
10372    (set_attr "mode" "DI")])
10374 ;; Convert lea to the lea pattern to avoid flags dependency.
10375 (define_split
10376   [(set (match_operand:DI 0 "register_operand" "")
10377         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10378                    (match_operand:QI 2 "immediate_operand" "")))
10379    (clobber (reg:CC FLAGS_REG))]
10380   "TARGET_64BIT && reload_completed
10381    && true_regnum (operands[0]) != true_regnum (operands[1])"
10382   [(set (match_dup 0)
10383         (mult:DI (match_dup 1)
10384                  (match_dup 2)))]
10385   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10387 ;; This pattern can't accept a variable shift count, since shifts by
10388 ;; zero don't affect the flags.  We assume that shifts by constant
10389 ;; zero are optimized away.
10390 (define_insn "*ashldi3_cmp_rex64"
10391   [(set (reg FLAGS_REG)
10392         (compare
10393           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10394                      (match_operand:QI 2 "immediate_operand" "e"))
10395           (const_int 0)))
10396    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10397         (ashift:DI (match_dup 1) (match_dup 2)))]
10398   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10399    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10401   switch (get_attr_type (insn))
10402     {
10403     case TYPE_ALU:
10404       gcc_assert (operands[2] == const1_rtx);
10405       return "add{q}\t{%0, %0|%0, %0}";
10407     default:
10408       if (REG_P (operands[2]))
10409         return "sal{q}\t{%b2, %0|%0, %b2}";
10410       else if (operands[2] == const1_rtx
10411                && (TARGET_SHIFT1 || optimize_size))
10412         return "sal{q}\t%0";
10413       else
10414         return "sal{q}\t{%2, %0|%0, %2}";
10415     }
10417   [(set (attr "type")
10418      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10419                           (const_int 0))
10420                       (match_operand 0 "register_operand" ""))
10421                  (match_operand 2 "const1_operand" ""))
10422               (const_string "alu")
10423            ]
10424            (const_string "ishift")))
10425    (set_attr "mode" "DI")])
10427 (define_insn "*ashldi3_1"
10428   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10429         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10430                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10431    (clobber (reg:CC FLAGS_REG))]
10432   "!TARGET_64BIT"
10433   "#"
10434   [(set_attr "type" "multi")])
10436 ;; By default we don't ask for a scratch register, because when DImode
10437 ;; values are manipulated, registers are already at a premium.  But if
10438 ;; we have one handy, we won't turn it away.
10439 (define_peephole2
10440   [(match_scratch:SI 3 "r")
10441    (parallel [(set (match_operand:DI 0 "register_operand" "")
10442                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10443                               (match_operand:QI 2 "nonmemory_operand" "")))
10444               (clobber (reg:CC FLAGS_REG))])
10445    (match_dup 3)]
10446   "!TARGET_64BIT && TARGET_CMOVE"
10447   [(const_int 0)]
10448   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10450 (define_split
10451   [(set (match_operand:DI 0 "register_operand" "")
10452         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10453                    (match_operand:QI 2 "nonmemory_operand" "")))
10454    (clobber (reg:CC FLAGS_REG))]
10455   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10456                      ? flow2_completed : reload_completed)"
10457   [(const_int 0)]
10458   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10460 (define_insn "x86_shld_1"
10461   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10462         (ior:SI (ashift:SI (match_dup 0)
10463                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10464                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10465                   (minus:QI (const_int 32) (match_dup 2)))))
10466    (clobber (reg:CC FLAGS_REG))]
10467   ""
10468   "@
10469    shld{l}\t{%2, %1, %0|%0, %1, %2}
10470    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10471   [(set_attr "type" "ishift")
10472    (set_attr "prefix_0f" "1")
10473    (set_attr "mode" "SI")
10474    (set_attr "pent_pair" "np")
10475    (set_attr "athlon_decode" "vector")])
10477 (define_expand "x86_shift_adj_1"
10478   [(set (reg:CCZ FLAGS_REG)
10479         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10480                              (const_int 32))
10481                      (const_int 0)))
10482    (set (match_operand:SI 0 "register_operand" "")
10483         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10484                          (match_operand:SI 1 "register_operand" "")
10485                          (match_dup 0)))
10486    (set (match_dup 1)
10487         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10488                          (match_operand:SI 3 "register_operand" "r")
10489                          (match_dup 1)))]
10490   "TARGET_CMOVE"
10491   "")
10493 (define_expand "x86_shift_adj_2"
10494   [(use (match_operand:SI 0 "register_operand" ""))
10495    (use (match_operand:SI 1 "register_operand" ""))
10496    (use (match_operand:QI 2 "register_operand" ""))]
10497   ""
10499   rtx label = gen_label_rtx ();
10500   rtx tmp;
10502   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10504   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10505   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10506   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10507                               gen_rtx_LABEL_REF (VOIDmode, label),
10508                               pc_rtx);
10509   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10510   JUMP_LABEL (tmp) = label;
10512   emit_move_insn (operands[0], operands[1]);
10513   ix86_expand_clear (operands[1]);
10515   emit_label (label);
10516   LABEL_NUSES (label) = 1;
10518   DONE;
10521 (define_expand "ashlsi3"
10522   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10523         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10524                    (match_operand:QI 2 "nonmemory_operand" "")))
10525    (clobber (reg:CC FLAGS_REG))]
10526   ""
10527   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10529 (define_insn "*ashlsi3_1"
10530   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10531         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10532                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10533    (clobber (reg:CC FLAGS_REG))]
10534   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10536   switch (get_attr_type (insn))
10537     {
10538     case TYPE_ALU:
10539       gcc_assert (operands[2] == const1_rtx);
10540       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10541       return "add{l}\t{%0, %0|%0, %0}";
10543     case TYPE_LEA:
10544       return "#";
10546     default:
10547       if (REG_P (operands[2]))
10548         return "sal{l}\t{%b2, %0|%0, %b2}";
10549       else if (operands[2] == const1_rtx
10550                && (TARGET_SHIFT1 || optimize_size))
10551         return "sal{l}\t%0";
10552       else
10553         return "sal{l}\t{%2, %0|%0, %2}";
10554     }
10556   [(set (attr "type")
10557      (cond [(eq_attr "alternative" "1")
10558               (const_string "lea")
10559             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10560                           (const_int 0))
10561                       (match_operand 0 "register_operand" ""))
10562                  (match_operand 2 "const1_operand" ""))
10563               (const_string "alu")
10564            ]
10565            (const_string "ishift")))
10566    (set_attr "mode" "SI")])
10568 ;; Convert lea to the lea pattern to avoid flags dependency.
10569 (define_split
10570   [(set (match_operand 0 "register_operand" "")
10571         (ashift (match_operand 1 "index_register_operand" "")
10572                 (match_operand:QI 2 "const_int_operand" "")))
10573    (clobber (reg:CC FLAGS_REG))]
10574   "reload_completed
10575    && true_regnum (operands[0]) != true_regnum (operands[1])
10576    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10577   [(const_int 0)]
10579   rtx pat;
10580   enum machine_mode mode = GET_MODE (operands[0]);
10582   if (GET_MODE_SIZE (mode) < 4)
10583     operands[0] = gen_lowpart (SImode, operands[0]);
10584   if (mode != Pmode)
10585     operands[1] = gen_lowpart (Pmode, operands[1]);
10586   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10588   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10589   if (Pmode != SImode)
10590     pat = gen_rtx_SUBREG (SImode, pat, 0);
10591   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10592   DONE;
10595 ;; Rare case of shifting RSP is handled by generating move and shift
10596 (define_split
10597   [(set (match_operand 0 "register_operand" "")
10598         (ashift (match_operand 1 "register_operand" "")
10599                 (match_operand:QI 2 "const_int_operand" "")))
10600    (clobber (reg:CC FLAGS_REG))]
10601   "reload_completed
10602    && true_regnum (operands[0]) != true_regnum (operands[1])"
10603   [(const_int 0)]
10605   rtx pat, clob;
10606   emit_move_insn (operands[0], operands[1]);
10607   pat = gen_rtx_SET (VOIDmode, operands[0],
10608                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10609                                      operands[0], operands[2]));
10610   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10611   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10612   DONE;
10615 (define_insn "*ashlsi3_1_zext"
10616   [(set (match_operand:DI 0 "register_operand" "=r,r")
10617         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10618                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10619    (clobber (reg:CC FLAGS_REG))]
10620   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10622   switch (get_attr_type (insn))
10623     {
10624     case TYPE_ALU:
10625       gcc_assert (operands[2] == const1_rtx);
10626       return "add{l}\t{%k0, %k0|%k0, %k0}";
10628     case TYPE_LEA:
10629       return "#";
10631     default:
10632       if (REG_P (operands[2]))
10633         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10634       else if (operands[2] == const1_rtx
10635                && (TARGET_SHIFT1 || optimize_size))
10636         return "sal{l}\t%k0";
10637       else
10638         return "sal{l}\t{%2, %k0|%k0, %2}";
10639     }
10641   [(set (attr "type")
10642      (cond [(eq_attr "alternative" "1")
10643               (const_string "lea")
10644             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10645                      (const_int 0))
10646                  (match_operand 2 "const1_operand" ""))
10647               (const_string "alu")
10648            ]
10649            (const_string "ishift")))
10650    (set_attr "mode" "SI")])
10652 ;; Convert lea to the lea pattern to avoid flags dependency.
10653 (define_split
10654   [(set (match_operand:DI 0 "register_operand" "")
10655         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10656                                 (match_operand:QI 2 "const_int_operand" ""))))
10657    (clobber (reg:CC FLAGS_REG))]
10658   "TARGET_64BIT && reload_completed
10659    && true_regnum (operands[0]) != true_regnum (operands[1])"
10660   [(set (match_dup 0) (zero_extend:DI
10661                         (subreg:SI (mult:SI (match_dup 1)
10662                                             (match_dup 2)) 0)))]
10664   operands[1] = gen_lowpart (Pmode, operands[1]);
10665   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10668 ;; This pattern can't accept a variable shift count, since shifts by
10669 ;; zero don't affect the flags.  We assume that shifts by constant
10670 ;; zero are optimized away.
10671 (define_insn "*ashlsi3_cmp"
10672   [(set (reg FLAGS_REG)
10673         (compare
10674           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10675                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10676           (const_int 0)))
10677    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10678         (ashift:SI (match_dup 1) (match_dup 2)))]
10679   "ix86_match_ccmode (insn, CCGOCmode)
10680    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10682   switch (get_attr_type (insn))
10683     {
10684     case TYPE_ALU:
10685       gcc_assert (operands[2] == const1_rtx);
10686       return "add{l}\t{%0, %0|%0, %0}";
10688     default:
10689       if (REG_P (operands[2]))
10690         return "sal{l}\t{%b2, %0|%0, %b2}";
10691       else if (operands[2] == const1_rtx
10692                && (TARGET_SHIFT1 || optimize_size))
10693         return "sal{l}\t%0";
10694       else
10695         return "sal{l}\t{%2, %0|%0, %2}";
10696     }
10698   [(set (attr "type")
10699      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10700                           (const_int 0))
10701                       (match_operand 0 "register_operand" ""))
10702                  (match_operand 2 "const1_operand" ""))
10703               (const_string "alu")
10704            ]
10705            (const_string "ishift")))
10706    (set_attr "mode" "SI")])
10708 (define_insn "*ashlsi3_cmp_zext"
10709   [(set (reg FLAGS_REG)
10710         (compare
10711           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10712                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10713           (const_int 0)))
10714    (set (match_operand:DI 0 "register_operand" "=r")
10715         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10716   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10717    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10719   switch (get_attr_type (insn))
10720     {
10721     case TYPE_ALU:
10722       gcc_assert (operands[2] == const1_rtx);
10723       return "add{l}\t{%k0, %k0|%k0, %k0}";
10725     default:
10726       if (REG_P (operands[2]))
10727         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10728       else if (operands[2] == const1_rtx
10729                && (TARGET_SHIFT1 || optimize_size))
10730         return "sal{l}\t%k0";
10731       else
10732         return "sal{l}\t{%2, %k0|%k0, %2}";
10733     }
10735   [(set (attr "type")
10736      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10737                      (const_int 0))
10738                  (match_operand 2 "const1_operand" ""))
10739               (const_string "alu")
10740            ]
10741            (const_string "ishift")))
10742    (set_attr "mode" "SI")])
10744 (define_expand "ashlhi3"
10745   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10746         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10747                    (match_operand:QI 2 "nonmemory_operand" "")))
10748    (clobber (reg:CC FLAGS_REG))]
10749   "TARGET_HIMODE_MATH"
10750   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10752 (define_insn "*ashlhi3_1_lea"
10753   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10754         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10755                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10756    (clobber (reg:CC FLAGS_REG))]
10757   "!TARGET_PARTIAL_REG_STALL
10758    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10760   switch (get_attr_type (insn))
10761     {
10762     case TYPE_LEA:
10763       return "#";
10764     case TYPE_ALU:
10765       gcc_assert (operands[2] == const1_rtx);
10766       return "add{w}\t{%0, %0|%0, %0}";
10768     default:
10769       if (REG_P (operands[2]))
10770         return "sal{w}\t{%b2, %0|%0, %b2}";
10771       else if (operands[2] == const1_rtx
10772                && (TARGET_SHIFT1 || optimize_size))
10773         return "sal{w}\t%0";
10774       else
10775         return "sal{w}\t{%2, %0|%0, %2}";
10776     }
10778   [(set (attr "type")
10779      (cond [(eq_attr "alternative" "1")
10780               (const_string "lea")
10781             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10782                           (const_int 0))
10783                       (match_operand 0 "register_operand" ""))
10784                  (match_operand 2 "const1_operand" ""))
10785               (const_string "alu")
10786            ]
10787            (const_string "ishift")))
10788    (set_attr "mode" "HI,SI")])
10790 (define_insn "*ashlhi3_1"
10791   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10792         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10793                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10794    (clobber (reg:CC FLAGS_REG))]
10795   "TARGET_PARTIAL_REG_STALL
10796    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10798   switch (get_attr_type (insn))
10799     {
10800     case TYPE_ALU:
10801       gcc_assert (operands[2] == const1_rtx);
10802       return "add{w}\t{%0, %0|%0, %0}";
10804     default:
10805       if (REG_P (operands[2]))
10806         return "sal{w}\t{%b2, %0|%0, %b2}";
10807       else if (operands[2] == const1_rtx
10808                && (TARGET_SHIFT1 || optimize_size))
10809         return "sal{w}\t%0";
10810       else
10811         return "sal{w}\t{%2, %0|%0, %2}";
10812     }
10814   [(set (attr "type")
10815      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10816                           (const_int 0))
10817                       (match_operand 0 "register_operand" ""))
10818                  (match_operand 2 "const1_operand" ""))
10819               (const_string "alu")
10820            ]
10821            (const_string "ishift")))
10822    (set_attr "mode" "HI")])
10824 ;; This pattern can't accept a variable shift count, since shifts by
10825 ;; zero don't affect the flags.  We assume that shifts by constant
10826 ;; zero are optimized away.
10827 (define_insn "*ashlhi3_cmp"
10828   [(set (reg FLAGS_REG)
10829         (compare
10830           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10831                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10832           (const_int 0)))
10833    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10834         (ashift:HI (match_dup 1) (match_dup 2)))]
10835   "ix86_match_ccmode (insn, CCGOCmode)
10836    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10838   switch (get_attr_type (insn))
10839     {
10840     case TYPE_ALU:
10841       gcc_assert (operands[2] == const1_rtx);
10842       return "add{w}\t{%0, %0|%0, %0}";
10844     default:
10845       if (REG_P (operands[2]))
10846         return "sal{w}\t{%b2, %0|%0, %b2}";
10847       else if (operands[2] == const1_rtx
10848                && (TARGET_SHIFT1 || optimize_size))
10849         return "sal{w}\t%0";
10850       else
10851         return "sal{w}\t{%2, %0|%0, %2}";
10852     }
10854   [(set (attr "type")
10855      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10856                           (const_int 0))
10857                       (match_operand 0 "register_operand" ""))
10858                  (match_operand 2 "const1_operand" ""))
10859               (const_string "alu")
10860            ]
10861            (const_string "ishift")))
10862    (set_attr "mode" "HI")])
10864 (define_expand "ashlqi3"
10865   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10866         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10867                    (match_operand:QI 2 "nonmemory_operand" "")))
10868    (clobber (reg:CC FLAGS_REG))]
10869   "TARGET_QIMODE_MATH"
10870   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10872 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10874 (define_insn "*ashlqi3_1_lea"
10875   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10876         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10877                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10878    (clobber (reg:CC FLAGS_REG))]
10879   "!TARGET_PARTIAL_REG_STALL
10880    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10882   switch (get_attr_type (insn))
10883     {
10884     case TYPE_LEA:
10885       return "#";
10886     case TYPE_ALU:
10887       gcc_assert (operands[2] == const1_rtx);
10888       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10889         return "add{l}\t{%k0, %k0|%k0, %k0}";
10890       else
10891         return "add{b}\t{%0, %0|%0, %0}";
10893     default:
10894       if (REG_P (operands[2]))
10895         {
10896           if (get_attr_mode (insn) == MODE_SI)
10897             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10898           else
10899             return "sal{b}\t{%b2, %0|%0, %b2}";
10900         }
10901       else if (operands[2] == const1_rtx
10902                && (TARGET_SHIFT1 || optimize_size))
10903         {
10904           if (get_attr_mode (insn) == MODE_SI)
10905             return "sal{l}\t%0";
10906           else
10907             return "sal{b}\t%0";
10908         }
10909       else
10910         {
10911           if (get_attr_mode (insn) == MODE_SI)
10912             return "sal{l}\t{%2, %k0|%k0, %2}";
10913           else
10914             return "sal{b}\t{%2, %0|%0, %2}";
10915         }
10916     }
10918   [(set (attr "type")
10919      (cond [(eq_attr "alternative" "2")
10920               (const_string "lea")
10921             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10922                           (const_int 0))
10923                       (match_operand 0 "register_operand" ""))
10924                  (match_operand 2 "const1_operand" ""))
10925               (const_string "alu")
10926            ]
10927            (const_string "ishift")))
10928    (set_attr "mode" "QI,SI,SI")])
10930 (define_insn "*ashlqi3_1"
10931   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10932         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10933                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10934    (clobber (reg:CC FLAGS_REG))]
10935   "TARGET_PARTIAL_REG_STALL
10936    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10938   switch (get_attr_type (insn))
10939     {
10940     case TYPE_ALU:
10941       gcc_assert (operands[2] == const1_rtx);
10942       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10943         return "add{l}\t{%k0, %k0|%k0, %k0}";
10944       else
10945         return "add{b}\t{%0, %0|%0, %0}";
10947     default:
10948       if (REG_P (operands[2]))
10949         {
10950           if (get_attr_mode (insn) == MODE_SI)
10951             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10952           else
10953             return "sal{b}\t{%b2, %0|%0, %b2}";
10954         }
10955       else if (operands[2] == const1_rtx
10956                && (TARGET_SHIFT1 || optimize_size))
10957         {
10958           if (get_attr_mode (insn) == MODE_SI)
10959             return "sal{l}\t%0";
10960           else
10961             return "sal{b}\t%0";
10962         }
10963       else
10964         {
10965           if (get_attr_mode (insn) == MODE_SI)
10966             return "sal{l}\t{%2, %k0|%k0, %2}";
10967           else
10968             return "sal{b}\t{%2, %0|%0, %2}";
10969         }
10970     }
10972   [(set (attr "type")
10973      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974                           (const_int 0))
10975                       (match_operand 0 "register_operand" ""))
10976                  (match_operand 2 "const1_operand" ""))
10977               (const_string "alu")
10978            ]
10979            (const_string "ishift")))
10980    (set_attr "mode" "QI,SI")])
10982 ;; This pattern can't accept a variable shift count, since shifts by
10983 ;; zero don't affect the flags.  We assume that shifts by constant
10984 ;; zero are optimized away.
10985 (define_insn "*ashlqi3_cmp"
10986   [(set (reg FLAGS_REG)
10987         (compare
10988           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10989                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10990           (const_int 0)))
10991    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10992         (ashift:QI (match_dup 1) (match_dup 2)))]
10993   "ix86_match_ccmode (insn, CCGOCmode)
10994    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10996   switch (get_attr_type (insn))
10997     {
10998     case TYPE_ALU:
10999       gcc_assert (operands[2] == const1_rtx);
11000       return "add{b}\t{%0, %0|%0, %0}";
11002     default:
11003       if (REG_P (operands[2]))
11004         return "sal{b}\t{%b2, %0|%0, %b2}";
11005       else if (operands[2] == const1_rtx
11006                && (TARGET_SHIFT1 || optimize_size))
11007         return "sal{b}\t%0";
11008       else
11009         return "sal{b}\t{%2, %0|%0, %2}";
11010     }
11012   [(set (attr "type")
11013      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014                           (const_int 0))
11015                       (match_operand 0 "register_operand" ""))
11016                  (match_operand 2 "const1_operand" ""))
11017               (const_string "alu")
11018            ]
11019            (const_string "ishift")))
11020    (set_attr "mode" "QI")])
11022 ;; See comment above `ashldi3' about how this works.
11024 (define_expand "ashrti3"
11025   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11026                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11027                                 (match_operand:QI 2 "nonmemory_operand" "")))
11028               (clobber (reg:CC FLAGS_REG))])]
11029   "TARGET_64BIT"
11031   if (! immediate_operand (operands[2], QImode))
11032     {
11033       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11034       DONE;
11035     }
11036   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11037   DONE;
11040 (define_insn "ashrti3_1"
11041   [(set (match_operand:TI 0 "register_operand" "=r")
11042         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11043                      (match_operand:QI 2 "register_operand" "c")))
11044    (clobber (match_scratch:DI 3 "=&r"))
11045    (clobber (reg:CC FLAGS_REG))]
11046   "TARGET_64BIT"
11047   "#"
11048   [(set_attr "type" "multi")])
11050 (define_insn "*ashrti3_2"
11051   [(set (match_operand:TI 0 "register_operand" "=r")
11052         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11053                      (match_operand:QI 2 "immediate_operand" "O")))
11054    (clobber (reg:CC FLAGS_REG))]
11055   "TARGET_64BIT"
11056   "#"
11057   [(set_attr "type" "multi")])
11059 (define_split
11060   [(set (match_operand:TI 0 "register_operand" "")
11061         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11062                      (match_operand:QI 2 "register_operand" "")))
11063    (clobber (match_scratch:DI 3 ""))
11064    (clobber (reg:CC FLAGS_REG))]
11065   "TARGET_64BIT && reload_completed"
11066   [(const_int 0)]
11067   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11069 (define_split
11070   [(set (match_operand:TI 0 "register_operand" "")
11071         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11072                      (match_operand:QI 2 "immediate_operand" "")))
11073    (clobber (reg:CC FLAGS_REG))]
11074   "TARGET_64BIT && reload_completed"
11075   [(const_int 0)]
11076   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11078 (define_insn "x86_64_shrd"
11079   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11080         (ior:DI (ashiftrt:DI (match_dup 0)
11081                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11082                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11083                   (minus:QI (const_int 64) (match_dup 2)))))
11084    (clobber (reg:CC FLAGS_REG))]
11085   "TARGET_64BIT"
11086   "@
11087    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11088    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11089   [(set_attr "type" "ishift")
11090    (set_attr "prefix_0f" "1")
11091    (set_attr "mode" "DI")
11092    (set_attr "athlon_decode" "vector")])
11094 (define_expand "ashrdi3"
11095   [(set (match_operand:DI 0 "shiftdi_operand" "")
11096         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11097                      (match_operand:QI 2 "nonmemory_operand" "")))]
11098   ""
11099   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11101 (define_insn "*ashrdi3_63_rex64"
11102   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11103         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11104                      (match_operand:DI 2 "const_int_operand" "i,i")))
11105    (clobber (reg:CC FLAGS_REG))]
11106   "TARGET_64BIT && INTVAL (operands[2]) == 63
11107    && (TARGET_USE_CLTD || optimize_size)
11108    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11109   "@
11110    {cqto|cqo}
11111    sar{q}\t{%2, %0|%0, %2}"
11112   [(set_attr "type" "imovx,ishift")
11113    (set_attr "prefix_0f" "0,*")
11114    (set_attr "length_immediate" "0,*")
11115    (set_attr "modrm" "0,1")
11116    (set_attr "mode" "DI")])
11118 (define_insn "*ashrdi3_1_one_bit_rex64"
11119   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11120         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11121                      (match_operand:QI 2 "const1_operand" "")))
11122    (clobber (reg:CC FLAGS_REG))]
11123   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11124    && (TARGET_SHIFT1 || optimize_size)"
11125   "sar{q}\t%0"
11126   [(set_attr "type" "ishift")
11127    (set (attr "length") 
11128      (if_then_else (match_operand:DI 0 "register_operand" "") 
11129         (const_string "2")
11130         (const_string "*")))])
11132 (define_insn "*ashrdi3_1_rex64"
11133   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11134         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11135                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11136    (clobber (reg:CC FLAGS_REG))]
11137   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11138   "@
11139    sar{q}\t{%2, %0|%0, %2}
11140    sar{q}\t{%b2, %0|%0, %b2}"
11141   [(set_attr "type" "ishift")
11142    (set_attr "mode" "DI")])
11144 ;; This pattern can't accept a variable shift count, since shifts by
11145 ;; zero don't affect the flags.  We assume that shifts by constant
11146 ;; zero are optimized away.
11147 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11148   [(set (reg FLAGS_REG)
11149         (compare
11150           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11151                        (match_operand:QI 2 "const1_operand" ""))
11152           (const_int 0)))
11153    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11154         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11155   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11156    && (TARGET_SHIFT1 || optimize_size)
11157    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11158   "sar{q}\t%0"
11159   [(set_attr "type" "ishift")
11160    (set (attr "length") 
11161      (if_then_else (match_operand:DI 0 "register_operand" "") 
11162         (const_string "2")
11163         (const_string "*")))])
11165 ;; This pattern can't accept a variable shift count, since shifts by
11166 ;; zero don't affect the flags.  We assume that shifts by constant
11167 ;; zero are optimized away.
11168 (define_insn "*ashrdi3_cmp_rex64"
11169   [(set (reg FLAGS_REG)
11170         (compare
11171           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11172                        (match_operand:QI 2 "const_int_operand" "n"))
11173           (const_int 0)))
11174    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11175         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11176   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11177    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11178   "sar{q}\t{%2, %0|%0, %2}"
11179   [(set_attr "type" "ishift")
11180    (set_attr "mode" "DI")])
11182 (define_insn "*ashrdi3_1"
11183   [(set (match_operand:DI 0 "register_operand" "=r")
11184         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11185                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11186    (clobber (reg:CC FLAGS_REG))]
11187   "!TARGET_64BIT"
11188   "#"
11189   [(set_attr "type" "multi")])
11191 ;; By default we don't ask for a scratch register, because when DImode
11192 ;; values are manipulated, registers are already at a premium.  But if
11193 ;; we have one handy, we won't turn it away.
11194 (define_peephole2
11195   [(match_scratch:SI 3 "r")
11196    (parallel [(set (match_operand:DI 0 "register_operand" "")
11197                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11198                                 (match_operand:QI 2 "nonmemory_operand" "")))
11199               (clobber (reg:CC FLAGS_REG))])
11200    (match_dup 3)]
11201   "!TARGET_64BIT && TARGET_CMOVE"
11202   [(const_int 0)]
11203   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11205 (define_split
11206   [(set (match_operand:DI 0 "register_operand" "")
11207         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11208                      (match_operand:QI 2 "nonmemory_operand" "")))
11209    (clobber (reg:CC FLAGS_REG))]
11210   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11211                      ? flow2_completed : reload_completed)"
11212   [(const_int 0)]
11213   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11215 (define_insn "x86_shrd_1"
11216   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11217         (ior:SI (ashiftrt:SI (match_dup 0)
11218                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11219                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11220                   (minus:QI (const_int 32) (match_dup 2)))))
11221    (clobber (reg:CC FLAGS_REG))]
11222   ""
11223   "@
11224    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11225    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11226   [(set_attr "type" "ishift")
11227    (set_attr "prefix_0f" "1")
11228    (set_attr "pent_pair" "np")
11229    (set_attr "mode" "SI")])
11231 (define_expand "x86_shift_adj_3"
11232   [(use (match_operand:SI 0 "register_operand" ""))
11233    (use (match_operand:SI 1 "register_operand" ""))
11234    (use (match_operand:QI 2 "register_operand" ""))]
11235   ""
11237   rtx label = gen_label_rtx ();
11238   rtx tmp;
11240   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11242   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11243   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11244   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11245                               gen_rtx_LABEL_REF (VOIDmode, label),
11246                               pc_rtx);
11247   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11248   JUMP_LABEL (tmp) = label;
11250   emit_move_insn (operands[0], operands[1]);
11251   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11253   emit_label (label);
11254   LABEL_NUSES (label) = 1;
11256   DONE;
11259 (define_insn "ashrsi3_31"
11260   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11261         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11262                      (match_operand:SI 2 "const_int_operand" "i,i")))
11263    (clobber (reg:CC FLAGS_REG))]
11264   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11265    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11266   "@
11267    {cltd|cdq}
11268    sar{l}\t{%2, %0|%0, %2}"
11269   [(set_attr "type" "imovx,ishift")
11270    (set_attr "prefix_0f" "0,*")
11271    (set_attr "length_immediate" "0,*")
11272    (set_attr "modrm" "0,1")
11273    (set_attr "mode" "SI")])
11275 (define_insn "*ashrsi3_31_zext"
11276   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11277         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11278                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11279    (clobber (reg:CC FLAGS_REG))]
11280   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11281    && INTVAL (operands[2]) == 31
11282    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11283   "@
11284    {cltd|cdq}
11285    sar{l}\t{%2, %k0|%k0, %2}"
11286   [(set_attr "type" "imovx,ishift")
11287    (set_attr "prefix_0f" "0,*")
11288    (set_attr "length_immediate" "0,*")
11289    (set_attr "modrm" "0,1")
11290    (set_attr "mode" "SI")])
11292 (define_expand "ashrsi3"
11293   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11294         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11295                      (match_operand:QI 2 "nonmemory_operand" "")))
11296    (clobber (reg:CC FLAGS_REG))]
11297   ""
11298   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11300 (define_insn "*ashrsi3_1_one_bit"
11301   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11302         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11303                      (match_operand:QI 2 "const1_operand" "")))
11304    (clobber (reg:CC FLAGS_REG))]
11305   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11306    && (TARGET_SHIFT1 || optimize_size)"
11307   "sar{l}\t%0"
11308   [(set_attr "type" "ishift")
11309    (set (attr "length") 
11310      (if_then_else (match_operand:SI 0 "register_operand" "") 
11311         (const_string "2")
11312         (const_string "*")))])
11314 (define_insn "*ashrsi3_1_one_bit_zext"
11315   [(set (match_operand:DI 0 "register_operand" "=r")
11316         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11317                                      (match_operand:QI 2 "const1_operand" ""))))
11318    (clobber (reg:CC FLAGS_REG))]
11319   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11320    && (TARGET_SHIFT1 || optimize_size)"
11321   "sar{l}\t%k0"
11322   [(set_attr "type" "ishift")
11323    (set_attr "length" "2")])
11325 (define_insn "*ashrsi3_1"
11326   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11327         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11328                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11329    (clobber (reg:CC FLAGS_REG))]
11330   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11331   "@
11332    sar{l}\t{%2, %0|%0, %2}
11333    sar{l}\t{%b2, %0|%0, %b2}"
11334   [(set_attr "type" "ishift")
11335    (set_attr "mode" "SI")])
11337 (define_insn "*ashrsi3_1_zext"
11338   [(set (match_operand:DI 0 "register_operand" "=r,r")
11339         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11340                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11341    (clobber (reg:CC FLAGS_REG))]
11342   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11343   "@
11344    sar{l}\t{%2, %k0|%k0, %2}
11345    sar{l}\t{%b2, %k0|%k0, %b2}"
11346   [(set_attr "type" "ishift")
11347    (set_attr "mode" "SI")])
11349 ;; This pattern can't accept a variable shift count, since shifts by
11350 ;; zero don't affect the flags.  We assume that shifts by constant
11351 ;; zero are optimized away.
11352 (define_insn "*ashrsi3_one_bit_cmp"
11353   [(set (reg FLAGS_REG)
11354         (compare
11355           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11356                        (match_operand:QI 2 "const1_operand" ""))
11357           (const_int 0)))
11358    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11359         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11360   "ix86_match_ccmode (insn, CCGOCmode)
11361    && (TARGET_SHIFT1 || optimize_size)
11362    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11363   "sar{l}\t%0"
11364   [(set_attr "type" "ishift")
11365    (set (attr "length") 
11366      (if_then_else (match_operand:SI 0 "register_operand" "") 
11367         (const_string "2")
11368         (const_string "*")))])
11370 (define_insn "*ashrsi3_one_bit_cmp_zext"
11371   [(set (reg FLAGS_REG)
11372         (compare
11373           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11374                        (match_operand:QI 2 "const1_operand" ""))
11375           (const_int 0)))
11376    (set (match_operand:DI 0 "register_operand" "=r")
11377         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11378   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11379    && (TARGET_SHIFT1 || optimize_size)
11380    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11381   "sar{l}\t%k0"
11382   [(set_attr "type" "ishift")
11383    (set_attr "length" "2")])
11385 ;; This pattern can't accept a variable shift count, since shifts by
11386 ;; zero don't affect the flags.  We assume that shifts by constant
11387 ;; zero are optimized away.
11388 (define_insn "*ashrsi3_cmp"
11389   [(set (reg FLAGS_REG)
11390         (compare
11391           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11392                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11393           (const_int 0)))
11394    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11395         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11396   "ix86_match_ccmode (insn, CCGOCmode)
11397    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11398   "sar{l}\t{%2, %0|%0, %2}"
11399   [(set_attr "type" "ishift")
11400    (set_attr "mode" "SI")])
11402 (define_insn "*ashrsi3_cmp_zext"
11403   [(set (reg FLAGS_REG)
11404         (compare
11405           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11406                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11407           (const_int 0)))
11408    (set (match_operand:DI 0 "register_operand" "=r")
11409         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11410   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11411    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11412   "sar{l}\t{%2, %k0|%k0, %2}"
11413   [(set_attr "type" "ishift")
11414    (set_attr "mode" "SI")])
11416 (define_expand "ashrhi3"
11417   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11418         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11419                      (match_operand:QI 2 "nonmemory_operand" "")))
11420    (clobber (reg:CC FLAGS_REG))]
11421   "TARGET_HIMODE_MATH"
11422   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11424 (define_insn "*ashrhi3_1_one_bit"
11425   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11426         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11427                      (match_operand:QI 2 "const1_operand" "")))
11428    (clobber (reg:CC FLAGS_REG))]
11429   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11430    && (TARGET_SHIFT1 || optimize_size)"
11431   "sar{w}\t%0"
11432   [(set_attr "type" "ishift")
11433    (set (attr "length") 
11434      (if_then_else (match_operand 0 "register_operand" "") 
11435         (const_string "2")
11436         (const_string "*")))])
11438 (define_insn "*ashrhi3_1"
11439   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11440         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11441                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11442    (clobber (reg:CC FLAGS_REG))]
11443   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11444   "@
11445    sar{w}\t{%2, %0|%0, %2}
11446    sar{w}\t{%b2, %0|%0, %b2}"
11447   [(set_attr "type" "ishift")
11448    (set_attr "mode" "HI")])
11450 ;; This pattern can't accept a variable shift count, since shifts by
11451 ;; zero don't affect the flags.  We assume that shifts by constant
11452 ;; zero are optimized away.
11453 (define_insn "*ashrhi3_one_bit_cmp"
11454   [(set (reg FLAGS_REG)
11455         (compare
11456           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11457                        (match_operand:QI 2 "const1_operand" ""))
11458           (const_int 0)))
11459    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11460         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11461   "ix86_match_ccmode (insn, CCGOCmode)
11462    && (TARGET_SHIFT1 || optimize_size)
11463    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11464   "sar{w}\t%0"
11465   [(set_attr "type" "ishift")
11466    (set (attr "length") 
11467      (if_then_else (match_operand 0 "register_operand" "") 
11468         (const_string "2")
11469         (const_string "*")))])
11471 ;; This pattern can't accept a variable shift count, since shifts by
11472 ;; zero don't affect the flags.  We assume that shifts by constant
11473 ;; zero are optimized away.
11474 (define_insn "*ashrhi3_cmp"
11475   [(set (reg FLAGS_REG)
11476         (compare
11477           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11478                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11479           (const_int 0)))
11480    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11481         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11482   "ix86_match_ccmode (insn, CCGOCmode)
11483    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11484   "sar{w}\t{%2, %0|%0, %2}"
11485   [(set_attr "type" "ishift")
11486    (set_attr "mode" "HI")])
11488 (define_expand "ashrqi3"
11489   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11490         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11491                      (match_operand:QI 2 "nonmemory_operand" "")))
11492    (clobber (reg:CC FLAGS_REG))]
11493   "TARGET_QIMODE_MATH"
11494   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11496 (define_insn "*ashrqi3_1_one_bit"
11497   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11498         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11499                      (match_operand:QI 2 "const1_operand" "")))
11500    (clobber (reg:CC FLAGS_REG))]
11501   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11502    && (TARGET_SHIFT1 || optimize_size)"
11503   "sar{b}\t%0"
11504   [(set_attr "type" "ishift")
11505    (set (attr "length") 
11506      (if_then_else (match_operand 0 "register_operand" "") 
11507         (const_string "2")
11508         (const_string "*")))])
11510 (define_insn "*ashrqi3_1_one_bit_slp"
11511   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11512         (ashiftrt:QI (match_dup 0)
11513                      (match_operand:QI 1 "const1_operand" "")))
11514    (clobber (reg:CC FLAGS_REG))]
11515   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11516    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11517    && (TARGET_SHIFT1 || optimize_size)"
11518   "sar{b}\t%0"
11519   [(set_attr "type" "ishift1")
11520    (set (attr "length") 
11521      (if_then_else (match_operand 0 "register_operand" "") 
11522         (const_string "2")
11523         (const_string "*")))])
11525 (define_insn "*ashrqi3_1"
11526   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11527         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11528                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11529    (clobber (reg:CC FLAGS_REG))]
11530   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11531   "@
11532    sar{b}\t{%2, %0|%0, %2}
11533    sar{b}\t{%b2, %0|%0, %b2}"
11534   [(set_attr "type" "ishift")
11535    (set_attr "mode" "QI")])
11537 (define_insn "*ashrqi3_1_slp"
11538   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11539         (ashiftrt:QI (match_dup 0)
11540                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11541    (clobber (reg:CC FLAGS_REG))]
11542   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11543    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11544   "@
11545    sar{b}\t{%1, %0|%0, %1}
11546    sar{b}\t{%b1, %0|%0, %b1}"
11547   [(set_attr "type" "ishift1")
11548    (set_attr "mode" "QI")])
11550 ;; This pattern can't accept a variable shift count, since shifts by
11551 ;; zero don't affect the flags.  We assume that shifts by constant
11552 ;; zero are optimized away.
11553 (define_insn "*ashrqi3_one_bit_cmp"
11554   [(set (reg FLAGS_REG)
11555         (compare
11556           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11557                        (match_operand:QI 2 "const1_operand" "I"))
11558           (const_int 0)))
11559    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11560         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11561   "ix86_match_ccmode (insn, CCGOCmode)
11562    && (TARGET_SHIFT1 || optimize_size)
11563    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11564   "sar{b}\t%0"
11565   [(set_attr "type" "ishift")
11566    (set (attr "length") 
11567      (if_then_else (match_operand 0 "register_operand" "") 
11568         (const_string "2")
11569         (const_string "*")))])
11571 ;; This pattern can't accept a variable shift count, since shifts by
11572 ;; zero don't affect the flags.  We assume that shifts by constant
11573 ;; zero are optimized away.
11574 (define_insn "*ashrqi3_cmp"
11575   [(set (reg FLAGS_REG)
11576         (compare
11577           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11578                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11579           (const_int 0)))
11580    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11581         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11582   "ix86_match_ccmode (insn, CCGOCmode)
11583    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11584   "sar{b}\t{%2, %0|%0, %2}"
11585   [(set_attr "type" "ishift")
11586    (set_attr "mode" "QI")])
11588 ;; Logical shift instructions
11590 ;; See comment above `ashldi3' about how this works.
11592 (define_expand "lshrti3"
11593   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11594                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11595                                 (match_operand:QI 2 "nonmemory_operand" "")))
11596               (clobber (reg:CC FLAGS_REG))])]
11597   "TARGET_64BIT"
11599   if (! immediate_operand (operands[2], QImode))
11600     {
11601       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11602       DONE;
11603     }
11604   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11605   DONE;
11608 (define_insn "lshrti3_1"
11609   [(set (match_operand:TI 0 "register_operand" "=r")
11610         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11611                      (match_operand:QI 2 "register_operand" "c")))
11612    (clobber (match_scratch:DI 3 "=&r"))
11613    (clobber (reg:CC FLAGS_REG))]
11614   "TARGET_64BIT"
11615   "#"
11616   [(set_attr "type" "multi")])
11618 (define_insn "*lshrti3_2"
11619   [(set (match_operand:TI 0 "register_operand" "=r")
11620         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11621                      (match_operand:QI 2 "immediate_operand" "O")))
11622    (clobber (reg:CC FLAGS_REG))]
11623   "TARGET_64BIT"
11624   "#"
11625   [(set_attr "type" "multi")])
11627 (define_split 
11628   [(set (match_operand:TI 0 "register_operand" "")
11629         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11630                      (match_operand:QI 2 "register_operand" "")))
11631    (clobber (match_scratch:DI 3 ""))
11632    (clobber (reg:CC FLAGS_REG))]
11633   "TARGET_64BIT && reload_completed"
11634   [(const_int 0)]
11635   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11637 (define_split 
11638   [(set (match_operand:TI 0 "register_operand" "")
11639         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11640                      (match_operand:QI 2 "immediate_operand" "")))
11641    (clobber (reg:CC FLAGS_REG))]
11642   "TARGET_64BIT && reload_completed"
11643   [(const_int 0)]
11644   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11646 (define_expand "lshrdi3"
11647   [(set (match_operand:DI 0 "shiftdi_operand" "")
11648         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11649                      (match_operand:QI 2 "nonmemory_operand" "")))]
11650   ""
11651   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11653 (define_insn "*lshrdi3_1_one_bit_rex64"
11654   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11655         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11656                      (match_operand:QI 2 "const1_operand" "")))
11657    (clobber (reg:CC FLAGS_REG))]
11658   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11659    && (TARGET_SHIFT1 || optimize_size)"
11660   "shr{q}\t%0"
11661   [(set_attr "type" "ishift")
11662    (set (attr "length") 
11663      (if_then_else (match_operand:DI 0 "register_operand" "") 
11664         (const_string "2")
11665         (const_string "*")))])
11667 (define_insn "*lshrdi3_1_rex64"
11668   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11669         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11670                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11671    (clobber (reg:CC FLAGS_REG))]
11672   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11673   "@
11674    shr{q}\t{%2, %0|%0, %2}
11675    shr{q}\t{%b2, %0|%0, %b2}"
11676   [(set_attr "type" "ishift")
11677    (set_attr "mode" "DI")])
11679 ;; This pattern can't accept a variable shift count, since shifts by
11680 ;; zero don't affect the flags.  We assume that shifts by constant
11681 ;; zero are optimized away.
11682 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11683   [(set (reg FLAGS_REG)
11684         (compare
11685           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11686                        (match_operand:QI 2 "const1_operand" ""))
11687           (const_int 0)))
11688    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11689         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11690   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11691    && (TARGET_SHIFT1 || optimize_size)
11692    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11693   "shr{q}\t%0"
11694   [(set_attr "type" "ishift")
11695    (set (attr "length") 
11696      (if_then_else (match_operand:DI 0 "register_operand" "") 
11697         (const_string "2")
11698         (const_string "*")))])
11700 ;; This pattern can't accept a variable shift count, since shifts by
11701 ;; zero don't affect the flags.  We assume that shifts by constant
11702 ;; zero are optimized away.
11703 (define_insn "*lshrdi3_cmp_rex64"
11704   [(set (reg FLAGS_REG)
11705         (compare
11706           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11707                        (match_operand:QI 2 "const_int_operand" "e"))
11708           (const_int 0)))
11709    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11710         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11711   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11712    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11713   "shr{q}\t{%2, %0|%0, %2}"
11714   [(set_attr "type" "ishift")
11715    (set_attr "mode" "DI")])
11717 (define_insn "*lshrdi3_1"
11718   [(set (match_operand:DI 0 "register_operand" "=r")
11719         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11720                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11721    (clobber (reg:CC FLAGS_REG))]
11722   "!TARGET_64BIT"
11723   "#"
11724   [(set_attr "type" "multi")])
11726 ;; By default we don't ask for a scratch register, because when DImode
11727 ;; values are manipulated, registers are already at a premium.  But if
11728 ;; we have one handy, we won't turn it away.
11729 (define_peephole2
11730   [(match_scratch:SI 3 "r")
11731    (parallel [(set (match_operand:DI 0 "register_operand" "")
11732                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11733                                 (match_operand:QI 2 "nonmemory_operand" "")))
11734               (clobber (reg:CC FLAGS_REG))])
11735    (match_dup 3)]
11736   "!TARGET_64BIT && TARGET_CMOVE"
11737   [(const_int 0)]
11738   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11740 (define_split 
11741   [(set (match_operand:DI 0 "register_operand" "")
11742         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11743                      (match_operand:QI 2 "nonmemory_operand" "")))
11744    (clobber (reg:CC FLAGS_REG))]
11745   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11746                      ? flow2_completed : reload_completed)"
11747   [(const_int 0)]
11748   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11750 (define_expand "lshrsi3"
11751   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11752         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11753                      (match_operand:QI 2 "nonmemory_operand" "")))
11754    (clobber (reg:CC FLAGS_REG))]
11755   ""
11756   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11758 (define_insn "*lshrsi3_1_one_bit"
11759   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11760         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11761                      (match_operand:QI 2 "const1_operand" "")))
11762    (clobber (reg:CC FLAGS_REG))]
11763   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11764    && (TARGET_SHIFT1 || optimize_size)"
11765   "shr{l}\t%0"
11766   [(set_attr "type" "ishift")
11767    (set (attr "length") 
11768      (if_then_else (match_operand:SI 0 "register_operand" "") 
11769         (const_string "2")
11770         (const_string "*")))])
11772 (define_insn "*lshrsi3_1_one_bit_zext"
11773   [(set (match_operand:DI 0 "register_operand" "=r")
11774         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11775                      (match_operand:QI 2 "const1_operand" "")))
11776    (clobber (reg:CC FLAGS_REG))]
11777   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11778    && (TARGET_SHIFT1 || optimize_size)"
11779   "shr{l}\t%k0"
11780   [(set_attr "type" "ishift")
11781    (set_attr "length" "2")])
11783 (define_insn "*lshrsi3_1"
11784   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11785         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11786                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11787    (clobber (reg:CC FLAGS_REG))]
11788   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11789   "@
11790    shr{l}\t{%2, %0|%0, %2}
11791    shr{l}\t{%b2, %0|%0, %b2}"
11792   [(set_attr "type" "ishift")
11793    (set_attr "mode" "SI")])
11795 (define_insn "*lshrsi3_1_zext"
11796   [(set (match_operand:DI 0 "register_operand" "=r,r")
11797         (zero_extend:DI
11798           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11799                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11800    (clobber (reg:CC FLAGS_REG))]
11801   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11802   "@
11803    shr{l}\t{%2, %k0|%k0, %2}
11804    shr{l}\t{%b2, %k0|%k0, %b2}"
11805   [(set_attr "type" "ishift")
11806    (set_attr "mode" "SI")])
11808 ;; This pattern can't accept a variable shift count, since shifts by
11809 ;; zero don't affect the flags.  We assume that shifts by constant
11810 ;; zero are optimized away.
11811 (define_insn "*lshrsi3_one_bit_cmp"
11812   [(set (reg FLAGS_REG)
11813         (compare
11814           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11815                        (match_operand:QI 2 "const1_operand" ""))
11816           (const_int 0)))
11817    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11818         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11819   "ix86_match_ccmode (insn, CCGOCmode)
11820    && (TARGET_SHIFT1 || optimize_size)
11821    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822   "shr{l}\t%0"
11823   [(set_attr "type" "ishift")
11824    (set (attr "length") 
11825      (if_then_else (match_operand:SI 0 "register_operand" "") 
11826         (const_string "2")
11827         (const_string "*")))])
11829 (define_insn "*lshrsi3_cmp_one_bit_zext"
11830   [(set (reg FLAGS_REG)
11831         (compare
11832           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11833                        (match_operand:QI 2 "const1_operand" ""))
11834           (const_int 0)))
11835    (set (match_operand:DI 0 "register_operand" "=r")
11836         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11837   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11838    && (TARGET_SHIFT1 || optimize_size)
11839    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11840   "shr{l}\t%k0"
11841   [(set_attr "type" "ishift")
11842    (set_attr "length" "2")])
11844 ;; This pattern can't accept a variable shift count, since shifts by
11845 ;; zero don't affect the flags.  We assume that shifts by constant
11846 ;; zero are optimized away.
11847 (define_insn "*lshrsi3_cmp"
11848   [(set (reg FLAGS_REG)
11849         (compare
11850           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11851                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11852           (const_int 0)))
11853    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11854         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11855   "ix86_match_ccmode (insn, CCGOCmode)
11856    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11857   "shr{l}\t{%2, %0|%0, %2}"
11858   [(set_attr "type" "ishift")
11859    (set_attr "mode" "SI")])
11861 (define_insn "*lshrsi3_cmp_zext"
11862   [(set (reg FLAGS_REG)
11863         (compare
11864           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11865                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11866           (const_int 0)))
11867    (set (match_operand:DI 0 "register_operand" "=r")
11868         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11869   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11870    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871   "shr{l}\t{%2, %k0|%k0, %2}"
11872   [(set_attr "type" "ishift")
11873    (set_attr "mode" "SI")])
11875 (define_expand "lshrhi3"
11876   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11877         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11878                      (match_operand:QI 2 "nonmemory_operand" "")))
11879    (clobber (reg:CC FLAGS_REG))]
11880   "TARGET_HIMODE_MATH"
11881   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11883 (define_insn "*lshrhi3_1_one_bit"
11884   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11885         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11886                      (match_operand:QI 2 "const1_operand" "")))
11887    (clobber (reg:CC FLAGS_REG))]
11888   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11889    && (TARGET_SHIFT1 || optimize_size)"
11890   "shr{w}\t%0"
11891   [(set_attr "type" "ishift")
11892    (set (attr "length") 
11893      (if_then_else (match_operand 0 "register_operand" "") 
11894         (const_string "2")
11895         (const_string "*")))])
11897 (define_insn "*lshrhi3_1"
11898   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11899         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11900                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11901    (clobber (reg:CC FLAGS_REG))]
11902   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11903   "@
11904    shr{w}\t{%2, %0|%0, %2}
11905    shr{w}\t{%b2, %0|%0, %b2}"
11906   [(set_attr "type" "ishift")
11907    (set_attr "mode" "HI")])
11909 ;; This pattern can't accept a variable shift count, since shifts by
11910 ;; zero don't affect the flags.  We assume that shifts by constant
11911 ;; zero are optimized away.
11912 (define_insn "*lshrhi3_one_bit_cmp"
11913   [(set (reg FLAGS_REG)
11914         (compare
11915           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11916                        (match_operand:QI 2 "const1_operand" ""))
11917           (const_int 0)))
11918    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11919         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11920   "ix86_match_ccmode (insn, CCGOCmode)
11921    && (TARGET_SHIFT1 || optimize_size)
11922    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11923   "shr{w}\t%0"
11924   [(set_attr "type" "ishift")
11925    (set (attr "length") 
11926      (if_then_else (match_operand:SI 0 "register_operand" "") 
11927         (const_string "2")
11928         (const_string "*")))])
11930 ;; This pattern can't accept a variable shift count, since shifts by
11931 ;; zero don't affect the flags.  We assume that shifts by constant
11932 ;; zero are optimized away.
11933 (define_insn "*lshrhi3_cmp"
11934   [(set (reg FLAGS_REG)
11935         (compare
11936           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11937                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11938           (const_int 0)))
11939    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11940         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11941   "ix86_match_ccmode (insn, CCGOCmode)
11942    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11943   "shr{w}\t{%2, %0|%0, %2}"
11944   [(set_attr "type" "ishift")
11945    (set_attr "mode" "HI")])
11947 (define_expand "lshrqi3"
11948   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11949         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11950                      (match_operand:QI 2 "nonmemory_operand" "")))
11951    (clobber (reg:CC FLAGS_REG))]
11952   "TARGET_QIMODE_MATH"
11953   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11955 (define_insn "*lshrqi3_1_one_bit"
11956   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11957         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11958                      (match_operand:QI 2 "const1_operand" "")))
11959    (clobber (reg:CC FLAGS_REG))]
11960   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11961    && (TARGET_SHIFT1 || optimize_size)"
11962   "shr{b}\t%0"
11963   [(set_attr "type" "ishift")
11964    (set (attr "length") 
11965      (if_then_else (match_operand 0 "register_operand" "") 
11966         (const_string "2")
11967         (const_string "*")))])
11969 (define_insn "*lshrqi3_1_one_bit_slp"
11970   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11971         (lshiftrt:QI (match_dup 0)
11972                      (match_operand:QI 1 "const1_operand" "")))
11973    (clobber (reg:CC FLAGS_REG))]
11974   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11975    && (TARGET_SHIFT1 || optimize_size)"
11976   "shr{b}\t%0"
11977   [(set_attr "type" "ishift1")
11978    (set (attr "length") 
11979      (if_then_else (match_operand 0 "register_operand" "") 
11980         (const_string "2")
11981         (const_string "*")))])
11983 (define_insn "*lshrqi3_1"
11984   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11985         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11986                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11987    (clobber (reg:CC FLAGS_REG))]
11988   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11989   "@
11990    shr{b}\t{%2, %0|%0, %2}
11991    shr{b}\t{%b2, %0|%0, %b2}"
11992   [(set_attr "type" "ishift")
11993    (set_attr "mode" "QI")])
11995 (define_insn "*lshrqi3_1_slp"
11996   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11997         (lshiftrt:QI (match_dup 0)
11998                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11999    (clobber (reg:CC FLAGS_REG))]
12000   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12001    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12002   "@
12003    shr{b}\t{%1, %0|%0, %1}
12004    shr{b}\t{%b1, %0|%0, %b1}"
12005   [(set_attr "type" "ishift1")
12006    (set_attr "mode" "QI")])
12008 ;; This pattern can't accept a variable shift count, since shifts by
12009 ;; zero don't affect the flags.  We assume that shifts by constant
12010 ;; zero are optimized away.
12011 (define_insn "*lshrqi2_one_bit_cmp"
12012   [(set (reg FLAGS_REG)
12013         (compare
12014           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12015                        (match_operand:QI 2 "const1_operand" ""))
12016           (const_int 0)))
12017    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12018         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12019   "ix86_match_ccmode (insn, CCGOCmode)
12020    && (TARGET_SHIFT1 || optimize_size)
12021    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12022   "shr{b}\t%0"
12023   [(set_attr "type" "ishift")
12024    (set (attr "length") 
12025      (if_then_else (match_operand:SI 0 "register_operand" "") 
12026         (const_string "2")
12027         (const_string "*")))])
12029 ;; This pattern can't accept a variable shift count, since shifts by
12030 ;; zero don't affect the flags.  We assume that shifts by constant
12031 ;; zero are optimized away.
12032 (define_insn "*lshrqi2_cmp"
12033   [(set (reg FLAGS_REG)
12034         (compare
12035           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12036                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12037           (const_int 0)))
12038    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12039         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12040   "ix86_match_ccmode (insn, CCGOCmode)
12041    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12042   "shr{b}\t{%2, %0|%0, %2}"
12043   [(set_attr "type" "ishift")
12044    (set_attr "mode" "QI")])
12046 ;; Rotate instructions
12048 (define_expand "rotldi3"
12049   [(set (match_operand:DI 0 "shiftdi_operand" "")
12050         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12051                    (match_operand:QI 2 "nonmemory_operand" "")))
12052    (clobber (reg:CC FLAGS_REG))]
12053  ""
12055   if (TARGET_64BIT)
12056     {
12057       ix86_expand_binary_operator (ROTATE, DImode, operands);
12058       DONE;
12059     }
12060   if (!const_1_to_31_operand (operands[2], VOIDmode))
12061     FAIL;
12062   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12063   DONE;
12066 ;; Implement rotation using two double-precision shift instructions
12067 ;; and a scratch register.   
12068 (define_insn_and_split "ix86_rotldi3"
12069  [(set (match_operand:DI 0 "register_operand" "=r")
12070        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12071                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12072   (clobber (reg:CC FLAGS_REG))
12073   (clobber (match_scratch:SI 3 "=&r"))]
12074  "!TARGET_64BIT"
12075  "" 
12076  "&& reload_completed"
12077  [(set (match_dup 3) (match_dup 4))
12078   (parallel
12079    [(set (match_dup 4)
12080          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12081                  (lshiftrt:SI (match_dup 5)
12082                               (minus:QI (const_int 32) (match_dup 2)))))
12083     (clobber (reg:CC FLAGS_REG))])
12084   (parallel
12085    [(set (match_dup 5)
12086          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12087                  (lshiftrt:SI (match_dup 3)
12088                               (minus:QI (const_int 32) (match_dup 2)))))
12089     (clobber (reg:CC FLAGS_REG))])]
12090  "split_di (operands, 1, operands + 4, operands + 5);")
12092 (define_insn "*rotlsi3_1_one_bit_rex64"
12093   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12094         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12095                    (match_operand:QI 2 "const1_operand" "")))
12096    (clobber (reg:CC FLAGS_REG))]
12097   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12098    && (TARGET_SHIFT1 || optimize_size)"
12099   "rol{q}\t%0"
12100   [(set_attr "type" "rotate")
12101    (set (attr "length") 
12102      (if_then_else (match_operand:DI 0 "register_operand" "") 
12103         (const_string "2")
12104         (const_string "*")))])
12106 (define_insn "*rotldi3_1_rex64"
12107   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12108         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12109                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12110    (clobber (reg:CC FLAGS_REG))]
12111   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12112   "@
12113    rol{q}\t{%2, %0|%0, %2}
12114    rol{q}\t{%b2, %0|%0, %b2}"
12115   [(set_attr "type" "rotate")
12116    (set_attr "mode" "DI")])
12118 (define_expand "rotlsi3"
12119   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12120         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12121                    (match_operand:QI 2 "nonmemory_operand" "")))
12122    (clobber (reg:CC FLAGS_REG))]
12123   ""
12124   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12126 (define_insn "*rotlsi3_1_one_bit"
12127   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12128         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12129                    (match_operand:QI 2 "const1_operand" "")))
12130    (clobber (reg:CC FLAGS_REG))]
12131   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12132    && (TARGET_SHIFT1 || optimize_size)"
12133   "rol{l}\t%0"
12134   [(set_attr "type" "rotate")
12135    (set (attr "length") 
12136      (if_then_else (match_operand:SI 0 "register_operand" "") 
12137         (const_string "2")
12138         (const_string "*")))])
12140 (define_insn "*rotlsi3_1_one_bit_zext"
12141   [(set (match_operand:DI 0 "register_operand" "=r")
12142         (zero_extend:DI
12143           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12144                      (match_operand:QI 2 "const1_operand" ""))))
12145    (clobber (reg:CC FLAGS_REG))]
12146   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12147    && (TARGET_SHIFT1 || optimize_size)"
12148   "rol{l}\t%k0"
12149   [(set_attr "type" "rotate")
12150    (set_attr "length" "2")])
12152 (define_insn "*rotlsi3_1"
12153   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12154         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12155                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12156    (clobber (reg:CC FLAGS_REG))]
12157   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12158   "@
12159    rol{l}\t{%2, %0|%0, %2}
12160    rol{l}\t{%b2, %0|%0, %b2}"
12161   [(set_attr "type" "rotate")
12162    (set_attr "mode" "SI")])
12164 (define_insn "*rotlsi3_1_zext"
12165   [(set (match_operand:DI 0 "register_operand" "=r,r")
12166         (zero_extend:DI
12167           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12168                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12169    (clobber (reg:CC FLAGS_REG))]
12170   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12171   "@
12172    rol{l}\t{%2, %k0|%k0, %2}
12173    rol{l}\t{%b2, %k0|%k0, %b2}"
12174   [(set_attr "type" "rotate")
12175    (set_attr "mode" "SI")])
12177 (define_expand "rotlhi3"
12178   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12179         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12180                    (match_operand:QI 2 "nonmemory_operand" "")))
12181    (clobber (reg:CC FLAGS_REG))]
12182   "TARGET_HIMODE_MATH"
12183   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12185 (define_insn "*rotlhi3_1_one_bit"
12186   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12187         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12188                    (match_operand:QI 2 "const1_operand" "")))
12189    (clobber (reg:CC FLAGS_REG))]
12190   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12191    && (TARGET_SHIFT1 || optimize_size)"
12192   "rol{w}\t%0"
12193   [(set_attr "type" "rotate")
12194    (set (attr "length") 
12195      (if_then_else (match_operand 0 "register_operand" "") 
12196         (const_string "2")
12197         (const_string "*")))])
12199 (define_insn "*rotlhi3_1"
12200   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12201         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12202                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12203    (clobber (reg:CC FLAGS_REG))]
12204   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12205   "@
12206    rol{w}\t{%2, %0|%0, %2}
12207    rol{w}\t{%b2, %0|%0, %b2}"
12208   [(set_attr "type" "rotate")
12209    (set_attr "mode" "HI")])
12211 (define_expand "rotlqi3"
12212   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12213         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12214                    (match_operand:QI 2 "nonmemory_operand" "")))
12215    (clobber (reg:CC FLAGS_REG))]
12216   "TARGET_QIMODE_MATH"
12217   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12219 (define_insn "*rotlqi3_1_one_bit_slp"
12220   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12221         (rotate:QI (match_dup 0)
12222                    (match_operand:QI 1 "const1_operand" "")))
12223    (clobber (reg:CC FLAGS_REG))]
12224   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12225    && (TARGET_SHIFT1 || optimize_size)"
12226   "rol{b}\t%0"
12227   [(set_attr "type" "rotate1")
12228    (set (attr "length") 
12229      (if_then_else (match_operand 0 "register_operand" "") 
12230         (const_string "2")
12231         (const_string "*")))])
12233 (define_insn "*rotlqi3_1_one_bit"
12234   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12235         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12236                    (match_operand:QI 2 "const1_operand" "")))
12237    (clobber (reg:CC FLAGS_REG))]
12238   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12239    && (TARGET_SHIFT1 || optimize_size)"
12240   "rol{b}\t%0"
12241   [(set_attr "type" "rotate")
12242    (set (attr "length") 
12243      (if_then_else (match_operand 0 "register_operand" "") 
12244         (const_string "2")
12245         (const_string "*")))])
12247 (define_insn "*rotlqi3_1_slp"
12248   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12249         (rotate:QI (match_dup 0)
12250                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12251    (clobber (reg:CC FLAGS_REG))]
12252   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12253    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12254   "@
12255    rol{b}\t{%1, %0|%0, %1}
12256    rol{b}\t{%b1, %0|%0, %b1}"
12257   [(set_attr "type" "rotate1")
12258    (set_attr "mode" "QI")])
12260 (define_insn "*rotlqi3_1"
12261   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12262         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12263                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12264    (clobber (reg:CC FLAGS_REG))]
12265   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12266   "@
12267    rol{b}\t{%2, %0|%0, %2}
12268    rol{b}\t{%b2, %0|%0, %b2}"
12269   [(set_attr "type" "rotate")
12270    (set_attr "mode" "QI")])
12272 (define_expand "rotrdi3"
12273   [(set (match_operand:DI 0 "shiftdi_operand" "")
12274         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12275                    (match_operand:QI 2 "nonmemory_operand" "")))
12276    (clobber (reg:CC FLAGS_REG))]
12277  ""
12279   if (TARGET_64BIT)
12280     {
12281       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12282       DONE;
12283     }
12284   if (!const_1_to_31_operand (operands[2], VOIDmode))
12285     FAIL;
12286   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12287   DONE;
12289   
12290 ;; Implement rotation using two double-precision shift instructions
12291 ;; and a scratch register.   
12292 (define_insn_and_split "ix86_rotrdi3"
12293  [(set (match_operand:DI 0 "register_operand" "=r")
12294        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12295                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12296   (clobber (reg:CC FLAGS_REG))
12297   (clobber (match_scratch:SI 3 "=&r"))]
12298  "!TARGET_64BIT"
12299  ""
12300  "&& reload_completed"
12301  [(set (match_dup 3) (match_dup 4))
12302   (parallel
12303    [(set (match_dup 4)
12304          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12305                  (ashift:SI (match_dup 5)
12306                             (minus:QI (const_int 32) (match_dup 2)))))
12307     (clobber (reg:CC FLAGS_REG))])
12308   (parallel
12309    [(set (match_dup 5)
12310          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12311                  (ashift:SI (match_dup 3)
12312                             (minus:QI (const_int 32) (match_dup 2)))))
12313     (clobber (reg:CC FLAGS_REG))])]
12314  "split_di (operands, 1, operands + 4, operands + 5);")
12316 (define_insn "*rotrdi3_1_one_bit_rex64"
12317   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12318         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12319                      (match_operand:QI 2 "const1_operand" "")))
12320    (clobber (reg:CC FLAGS_REG))]
12321   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12322    && (TARGET_SHIFT1 || optimize_size)"
12323   "ror{q}\t%0"
12324   [(set_attr "type" "rotate")
12325    (set (attr "length") 
12326      (if_then_else (match_operand:DI 0 "register_operand" "") 
12327         (const_string "2")
12328         (const_string "*")))])
12330 (define_insn "*rotrdi3_1_rex64"
12331   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12332         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12333                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12334    (clobber (reg:CC FLAGS_REG))]
12335   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12336   "@
12337    ror{q}\t{%2, %0|%0, %2}
12338    ror{q}\t{%b2, %0|%0, %b2}"
12339   [(set_attr "type" "rotate")
12340    (set_attr "mode" "DI")])
12342 (define_expand "rotrsi3"
12343   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12344         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12345                      (match_operand:QI 2 "nonmemory_operand" "")))
12346    (clobber (reg:CC FLAGS_REG))]
12347   ""
12348   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12350 (define_insn "*rotrsi3_1_one_bit"
12351   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12352         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12353                      (match_operand:QI 2 "const1_operand" "")))
12354    (clobber (reg:CC FLAGS_REG))]
12355   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12356    && (TARGET_SHIFT1 || optimize_size)"
12357   "ror{l}\t%0"
12358   [(set_attr "type" "rotate")
12359    (set (attr "length") 
12360      (if_then_else (match_operand:SI 0 "register_operand" "") 
12361         (const_string "2")
12362         (const_string "*")))])
12364 (define_insn "*rotrsi3_1_one_bit_zext"
12365   [(set (match_operand:DI 0 "register_operand" "=r")
12366         (zero_extend:DI
12367           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12368                        (match_operand:QI 2 "const1_operand" ""))))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12371    && (TARGET_SHIFT1 || optimize_size)"
12372   "ror{l}\t%k0"
12373   [(set_attr "type" "rotate")
12374    (set (attr "length") 
12375      (if_then_else (match_operand:SI 0 "register_operand" "") 
12376         (const_string "2")
12377         (const_string "*")))])
12379 (define_insn "*rotrsi3_1"
12380   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12381         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12382                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12383    (clobber (reg:CC FLAGS_REG))]
12384   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12385   "@
12386    ror{l}\t{%2, %0|%0, %2}
12387    ror{l}\t{%b2, %0|%0, %b2}"
12388   [(set_attr "type" "rotate")
12389    (set_attr "mode" "SI")])
12391 (define_insn "*rotrsi3_1_zext"
12392   [(set (match_operand:DI 0 "register_operand" "=r,r")
12393         (zero_extend:DI
12394           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12395                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12396    (clobber (reg:CC FLAGS_REG))]
12397   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12398   "@
12399    ror{l}\t{%2, %k0|%k0, %2}
12400    ror{l}\t{%b2, %k0|%k0, %b2}"
12401   [(set_attr "type" "rotate")
12402    (set_attr "mode" "SI")])
12404 (define_expand "rotrhi3"
12405   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12406         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12407                      (match_operand:QI 2 "nonmemory_operand" "")))
12408    (clobber (reg:CC FLAGS_REG))]
12409   "TARGET_HIMODE_MATH"
12410   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12412 (define_insn "*rotrhi3_one_bit"
12413   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12414         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12415                      (match_operand:QI 2 "const1_operand" "")))
12416    (clobber (reg:CC FLAGS_REG))]
12417   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12418    && (TARGET_SHIFT1 || optimize_size)"
12419   "ror{w}\t%0"
12420   [(set_attr "type" "rotate")
12421    (set (attr "length") 
12422      (if_then_else (match_operand 0 "register_operand" "") 
12423         (const_string "2")
12424         (const_string "*")))])
12426 (define_insn "*rotrhi3"
12427   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12428         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12429                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12430    (clobber (reg:CC FLAGS_REG))]
12431   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12432   "@
12433    ror{w}\t{%2, %0|%0, %2}
12434    ror{w}\t{%b2, %0|%0, %b2}"
12435   [(set_attr "type" "rotate")
12436    (set_attr "mode" "HI")])
12438 (define_expand "rotrqi3"
12439   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12440         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12441                      (match_operand:QI 2 "nonmemory_operand" "")))
12442    (clobber (reg:CC FLAGS_REG))]
12443   "TARGET_QIMODE_MATH"
12444   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12446 (define_insn "*rotrqi3_1_one_bit"
12447   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12448         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12449                      (match_operand:QI 2 "const1_operand" "")))
12450    (clobber (reg:CC FLAGS_REG))]
12451   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12452    && (TARGET_SHIFT1 || optimize_size)"
12453   "ror{b}\t%0"
12454   [(set_attr "type" "rotate")
12455    (set (attr "length") 
12456      (if_then_else (match_operand 0 "register_operand" "") 
12457         (const_string "2")
12458         (const_string "*")))])
12460 (define_insn "*rotrqi3_1_one_bit_slp"
12461   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12462         (rotatert:QI (match_dup 0)
12463                      (match_operand:QI 1 "const1_operand" "")))
12464    (clobber (reg:CC FLAGS_REG))]
12465   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12466    && (TARGET_SHIFT1 || optimize_size)"
12467   "ror{b}\t%0"
12468   [(set_attr "type" "rotate1")
12469    (set (attr "length") 
12470      (if_then_else (match_operand 0 "register_operand" "") 
12471         (const_string "2")
12472         (const_string "*")))])
12474 (define_insn "*rotrqi3_1"
12475   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12476         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12477                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12478    (clobber (reg:CC FLAGS_REG))]
12479   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12480   "@
12481    ror{b}\t{%2, %0|%0, %2}
12482    ror{b}\t{%b2, %0|%0, %b2}"
12483   [(set_attr "type" "rotate")
12484    (set_attr "mode" "QI")])
12486 (define_insn "*rotrqi3_1_slp"
12487   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12488         (rotatert:QI (match_dup 0)
12489                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12490    (clobber (reg:CC FLAGS_REG))]
12491   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12492    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12493   "@
12494    ror{b}\t{%1, %0|%0, %1}
12495    ror{b}\t{%b1, %0|%0, %b1}"
12496   [(set_attr "type" "rotate1")
12497    (set_attr "mode" "QI")])
12499 ;; Bit set / bit test instructions
12501 (define_expand "extv"
12502   [(set (match_operand:SI 0 "register_operand" "")
12503         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12504                          (match_operand:SI 2 "const8_operand" "")
12505                          (match_operand:SI 3 "const8_operand" "")))]
12506   ""
12508   /* Handle extractions from %ah et al.  */
12509   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12510     FAIL;
12512   /* From mips.md: extract_bit_field doesn't verify that our source
12513      matches the predicate, so check it again here.  */
12514   if (! ext_register_operand (operands[1], VOIDmode))
12515     FAIL;
12518 (define_expand "extzv"
12519   [(set (match_operand:SI 0 "register_operand" "")
12520         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12521                          (match_operand:SI 2 "const8_operand" "")
12522                          (match_operand:SI 3 "const8_operand" "")))]
12523   ""
12525   /* Handle extractions from %ah et al.  */
12526   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12527     FAIL;
12529   /* From mips.md: extract_bit_field doesn't verify that our source
12530      matches the predicate, so check it again here.  */
12531   if (! ext_register_operand (operands[1], VOIDmode))
12532     FAIL;
12535 (define_expand "insv"
12536   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12537                       (match_operand 1 "const8_operand" "")
12538                       (match_operand 2 "const8_operand" ""))
12539         (match_operand 3 "register_operand" ""))]
12540   ""
12542   /* Handle insertions to %ah et al.  */
12543   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12544     FAIL;
12546   /* From mips.md: insert_bit_field doesn't verify that our source
12547      matches the predicate, so check it again here.  */
12548   if (! ext_register_operand (operands[0], VOIDmode))
12549     FAIL;
12551   if (TARGET_64BIT)
12552     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12553   else
12554     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12556   DONE;
12559 ;; %%% bts, btr, btc, bt.
12560 ;; In general these instructions are *slow* when applied to memory,
12561 ;; since they enforce atomic operation.  When applied to registers,
12562 ;; it depends on the cpu implementation.  They're never faster than
12563 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12564 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12565 ;; within the instruction itself, so operating on bits in the high
12566 ;; 32-bits of a register becomes easier.
12568 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12569 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12570 ;; negdf respectively, so they can never be disabled entirely.
12572 (define_insn "*btsq"
12573   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12574                          (const_int 1)
12575                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12576         (const_int 1))
12577    (clobber (reg:CC FLAGS_REG))]
12578   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12579   "bts{q} %1,%0"
12580   [(set_attr "type" "alu1")])
12582 (define_insn "*btrq"
12583   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12584                          (const_int 1)
12585                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12586         (const_int 0))
12587    (clobber (reg:CC FLAGS_REG))]
12588   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12589   "btr{q} %1,%0"
12590   [(set_attr "type" "alu1")])
12592 (define_insn "*btcq"
12593   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12594                          (const_int 1)
12595                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12596         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12597    (clobber (reg:CC FLAGS_REG))]
12598   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12599   "btc{q} %1,%0"
12600   [(set_attr "type" "alu1")])
12602 ;; Allow Nocona to avoid these instructions if a register is available.
12604 (define_peephole2
12605   [(match_scratch:DI 2 "r")
12606    (parallel [(set (zero_extract:DI
12607                      (match_operand:DI 0 "register_operand" "")
12608                      (const_int 1)
12609                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12610                    (const_int 1))
12611               (clobber (reg:CC FLAGS_REG))])]
12612   "TARGET_64BIT && !TARGET_USE_BT"
12613   [(const_int 0)]
12615   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12616   rtx op1;
12618   if (HOST_BITS_PER_WIDE_INT >= 64)
12619     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620   else if (i < HOST_BITS_PER_WIDE_INT)
12621     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12622   else
12623     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12625   op1 = immed_double_const (lo, hi, DImode);
12626   if (i >= 31)
12627     {
12628       emit_move_insn (operands[2], op1);
12629       op1 = operands[2];
12630     }
12632   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12633   DONE;
12636 (define_peephole2
12637   [(match_scratch:DI 2 "r")
12638    (parallel [(set (zero_extract:DI
12639                      (match_operand:DI 0 "register_operand" "")
12640                      (const_int 1)
12641                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12642                    (const_int 0))
12643               (clobber (reg:CC FLAGS_REG))])]
12644   "TARGET_64BIT && !TARGET_USE_BT"
12645   [(const_int 0)]
12647   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12648   rtx op1;
12650   if (HOST_BITS_PER_WIDE_INT >= 64)
12651     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652   else if (i < HOST_BITS_PER_WIDE_INT)
12653     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12654   else
12655     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12657   op1 = immed_double_const (~lo, ~hi, DImode);
12658   if (i >= 32)
12659     {
12660       emit_move_insn (operands[2], op1);
12661       op1 = operands[2];
12662     }
12664   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12665   DONE;
12668 (define_peephole2
12669   [(match_scratch:DI 2 "r")
12670    (parallel [(set (zero_extract:DI
12671                      (match_operand:DI 0 "register_operand" "")
12672                      (const_int 1)
12673                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12674               (not:DI (zero_extract:DI
12675                         (match_dup 0) (const_int 1) (match_dup 1))))
12676               (clobber (reg:CC FLAGS_REG))])]
12677   "TARGET_64BIT && !TARGET_USE_BT"
12678   [(const_int 0)]
12680   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12681   rtx op1;
12683   if (HOST_BITS_PER_WIDE_INT >= 64)
12684     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12685   else if (i < HOST_BITS_PER_WIDE_INT)
12686     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12687   else
12688     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12690   op1 = immed_double_const (lo, hi, DImode);
12691   if (i >= 31)
12692     {
12693       emit_move_insn (operands[2], op1);
12694       op1 = operands[2];
12695     }
12697   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12698   DONE;
12701 ;; Store-flag instructions.
12703 ;; For all sCOND expanders, also expand the compare or test insn that
12704 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12706 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
12707 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
12708 ;; way, which can later delete the movzx if only QImode is needed.
12710 (define_expand "seq"
12711   [(set (match_operand:QI 0 "register_operand" "")
12712         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12713   ""
12714   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12716 (define_expand "sne"
12717   [(set (match_operand:QI 0 "register_operand" "")
12718         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12719   ""
12720   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12722 (define_expand "sgt"
12723   [(set (match_operand:QI 0 "register_operand" "")
12724         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12725   ""
12726   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12728 (define_expand "sgtu"
12729   [(set (match_operand:QI 0 "register_operand" "")
12730         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12731   ""
12732   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12734 (define_expand "slt"
12735   [(set (match_operand:QI 0 "register_operand" "")
12736         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12737   ""
12738   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12740 (define_expand "sltu"
12741   [(set (match_operand:QI 0 "register_operand" "")
12742         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12743   ""
12744   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12746 (define_expand "sge"
12747   [(set (match_operand:QI 0 "register_operand" "")
12748         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12749   ""
12750   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12752 (define_expand "sgeu"
12753   [(set (match_operand:QI 0 "register_operand" "")
12754         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12755   ""
12756   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12758 (define_expand "sle"
12759   [(set (match_operand:QI 0 "register_operand" "")
12760         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12761   ""
12762   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12764 (define_expand "sleu"
12765   [(set (match_operand:QI 0 "register_operand" "")
12766         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12767   ""
12768   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12770 (define_expand "sunordered"
12771   [(set (match_operand:QI 0 "register_operand" "")
12772         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12773   "TARGET_80387 || TARGET_SSE"
12774   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12776 (define_expand "sordered"
12777   [(set (match_operand:QI 0 "register_operand" "")
12778         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12779   "TARGET_80387"
12780   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12782 (define_expand "suneq"
12783   [(set (match_operand:QI 0 "register_operand" "")
12784         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12785   "TARGET_80387 || TARGET_SSE"
12786   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12788 (define_expand "sunge"
12789   [(set (match_operand:QI 0 "register_operand" "")
12790         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12791   "TARGET_80387 || TARGET_SSE"
12792   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12794 (define_expand "sungt"
12795   [(set (match_operand:QI 0 "register_operand" "")
12796         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12797   "TARGET_80387 || TARGET_SSE"
12798   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12800 (define_expand "sunle"
12801   [(set (match_operand:QI 0 "register_operand" "")
12802         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12803   "TARGET_80387 || TARGET_SSE"
12804   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12806 (define_expand "sunlt"
12807   [(set (match_operand:QI 0 "register_operand" "")
12808         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12809   "TARGET_80387 || TARGET_SSE"
12810   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12812 (define_expand "sltgt"
12813   [(set (match_operand:QI 0 "register_operand" "")
12814         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12815   "TARGET_80387 || TARGET_SSE"
12816   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12818 (define_insn "*setcc_1"
12819   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12820         (match_operator:QI 1 "ix86_comparison_operator"
12821           [(reg FLAGS_REG) (const_int 0)]))]
12822   ""
12823   "set%C1\t%0"
12824   [(set_attr "type" "setcc")
12825    (set_attr "mode" "QI")])
12827 (define_insn "*setcc_2"
12828   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12829         (match_operator:QI 1 "ix86_comparison_operator"
12830           [(reg FLAGS_REG) (const_int 0)]))]
12831   ""
12832   "set%C1\t%0"
12833   [(set_attr "type" "setcc")
12834    (set_attr "mode" "QI")])
12836 ;; In general it is not safe to assume too much about CCmode registers,
12837 ;; so simplify-rtx stops when it sees a second one.  Under certain 
12838 ;; conditions this is safe on x86, so help combine not create
12840 ;;      seta    %al
12841 ;;      testb   %al, %al
12842 ;;      sete    %al
12844 (define_split 
12845   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12846         (ne:QI (match_operator 1 "ix86_comparison_operator"
12847                  [(reg FLAGS_REG) (const_int 0)])
12848             (const_int 0)))]
12849   ""
12850   [(set (match_dup 0) (match_dup 1))]
12852   PUT_MODE (operands[1], QImode);
12855 (define_split 
12856   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12857         (ne:QI (match_operator 1 "ix86_comparison_operator"
12858                  [(reg FLAGS_REG) (const_int 0)])
12859             (const_int 0)))]
12860   ""
12861   [(set (match_dup 0) (match_dup 1))]
12863   PUT_MODE (operands[1], QImode);
12866 (define_split 
12867   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12868         (eq:QI (match_operator 1 "ix86_comparison_operator"
12869                  [(reg FLAGS_REG) (const_int 0)])
12870             (const_int 0)))]
12871   ""
12872   [(set (match_dup 0) (match_dup 1))]
12874   rtx new_op1 = copy_rtx (operands[1]);
12875   operands[1] = new_op1;
12876   PUT_MODE (new_op1, QImode);
12877   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12878                                              GET_MODE (XEXP (new_op1, 0))));
12880   /* Make sure that (a) the CCmode we have for the flags is strong
12881      enough for the reversed compare or (b) we have a valid FP compare.  */
12882   if (! ix86_comparison_operator (new_op1, VOIDmode))
12883     FAIL;
12886 (define_split 
12887   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12888         (eq:QI (match_operator 1 "ix86_comparison_operator"
12889                  [(reg FLAGS_REG) (const_int 0)])
12890             (const_int 0)))]
12891   ""
12892   [(set (match_dup 0) (match_dup 1))]
12894   rtx new_op1 = copy_rtx (operands[1]);
12895   operands[1] = new_op1;
12896   PUT_MODE (new_op1, QImode);
12897   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12898                                              GET_MODE (XEXP (new_op1, 0))));
12900   /* Make sure that (a) the CCmode we have for the flags is strong
12901      enough for the reversed compare or (b) we have a valid FP compare.  */
12902   if (! ix86_comparison_operator (new_op1, VOIDmode))
12903     FAIL;
12906 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12907 ;; subsequent logical operations are used to imitate conditional moves.
12908 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12909 ;; it directly.
12911 (define_insn "*sse_setccsf"
12912   [(set (match_operand:SF 0 "register_operand" "=x")
12913         (match_operator:SF 1 "sse_comparison_operator"
12914           [(match_operand:SF 2 "register_operand" "0")
12915            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12916   "TARGET_SSE"
12917   "cmp%D1ss\t{%3, %0|%0, %3}"
12918   [(set_attr "type" "ssecmp")
12919    (set_attr "mode" "SF")])
12921 (define_insn "*sse_setccdf"
12922   [(set (match_operand:DF 0 "register_operand" "=Y")
12923         (match_operator:DF 1 "sse_comparison_operator"
12924           [(match_operand:DF 2 "register_operand" "0")
12925            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12926   "TARGET_SSE2"
12927   "cmp%D1sd\t{%3, %0|%0, %3}"
12928   [(set_attr "type" "ssecmp")
12929    (set_attr "mode" "DF")])
12931 ;; Basic conditional jump instructions.
12932 ;; We ignore the overflow flag for signed branch instructions.
12934 ;; For all bCOND expanders, also expand the compare or test insn that
12935 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
12937 (define_expand "beq"
12938   [(set (pc)
12939         (if_then_else (match_dup 1)
12940                       (label_ref (match_operand 0 "" ""))
12941                       (pc)))]
12942   ""
12943   "ix86_expand_branch (EQ, operands[0]); DONE;")
12945 (define_expand "bne"
12946   [(set (pc)
12947         (if_then_else (match_dup 1)
12948                       (label_ref (match_operand 0 "" ""))
12949                       (pc)))]
12950   ""
12951   "ix86_expand_branch (NE, operands[0]); DONE;")
12953 (define_expand "bgt"
12954   [(set (pc)
12955         (if_then_else (match_dup 1)
12956                       (label_ref (match_operand 0 "" ""))
12957                       (pc)))]
12958   ""
12959   "ix86_expand_branch (GT, operands[0]); DONE;")
12961 (define_expand "bgtu"
12962   [(set (pc)
12963         (if_then_else (match_dup 1)
12964                       (label_ref (match_operand 0 "" ""))
12965                       (pc)))]
12966   ""
12967   "ix86_expand_branch (GTU, operands[0]); DONE;")
12969 (define_expand "blt"
12970   [(set (pc)
12971         (if_then_else (match_dup 1)
12972                       (label_ref (match_operand 0 "" ""))
12973                       (pc)))]
12974   ""
12975   "ix86_expand_branch (LT, operands[0]); DONE;")
12977 (define_expand "bltu"
12978   [(set (pc)
12979         (if_then_else (match_dup 1)
12980                       (label_ref (match_operand 0 "" ""))
12981                       (pc)))]
12982   ""
12983   "ix86_expand_branch (LTU, operands[0]); DONE;")
12985 (define_expand "bge"
12986   [(set (pc)
12987         (if_then_else (match_dup 1)
12988                       (label_ref (match_operand 0 "" ""))
12989                       (pc)))]
12990   ""
12991   "ix86_expand_branch (GE, operands[0]); DONE;")
12993 (define_expand "bgeu"
12994   [(set (pc)
12995         (if_then_else (match_dup 1)
12996                       (label_ref (match_operand 0 "" ""))
12997                       (pc)))]
12998   ""
12999   "ix86_expand_branch (GEU, operands[0]); DONE;")
13001 (define_expand "ble"
13002   [(set (pc)
13003         (if_then_else (match_dup 1)
13004                       (label_ref (match_operand 0 "" ""))
13005                       (pc)))]
13006   ""
13007   "ix86_expand_branch (LE, operands[0]); DONE;")
13009 (define_expand "bleu"
13010   [(set (pc)
13011         (if_then_else (match_dup 1)
13012                       (label_ref (match_operand 0 "" ""))
13013                       (pc)))]
13014   ""
13015   "ix86_expand_branch (LEU, operands[0]); DONE;")
13017 (define_expand "bunordered"
13018   [(set (pc)
13019         (if_then_else (match_dup 1)
13020                       (label_ref (match_operand 0 "" ""))
13021                       (pc)))]
13022   "TARGET_80387 || TARGET_SSE_MATH"
13023   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13025 (define_expand "bordered"
13026   [(set (pc)
13027         (if_then_else (match_dup 1)
13028                       (label_ref (match_operand 0 "" ""))
13029                       (pc)))]
13030   "TARGET_80387 || TARGET_SSE_MATH"
13031   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13033 (define_expand "buneq"
13034   [(set (pc)
13035         (if_then_else (match_dup 1)
13036                       (label_ref (match_operand 0 "" ""))
13037                       (pc)))]
13038   "TARGET_80387 || TARGET_SSE_MATH"
13039   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13041 (define_expand "bunge"
13042   [(set (pc)
13043         (if_then_else (match_dup 1)
13044                       (label_ref (match_operand 0 "" ""))
13045                       (pc)))]
13046   "TARGET_80387 || TARGET_SSE_MATH"
13047   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13049 (define_expand "bungt"
13050   [(set (pc)
13051         (if_then_else (match_dup 1)
13052                       (label_ref (match_operand 0 "" ""))
13053                       (pc)))]
13054   "TARGET_80387 || TARGET_SSE_MATH"
13055   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13057 (define_expand "bunle"
13058   [(set (pc)
13059         (if_then_else (match_dup 1)
13060                       (label_ref (match_operand 0 "" ""))
13061                       (pc)))]
13062   "TARGET_80387 || TARGET_SSE_MATH"
13063   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13065 (define_expand "bunlt"
13066   [(set (pc)
13067         (if_then_else (match_dup 1)
13068                       (label_ref (match_operand 0 "" ""))
13069                       (pc)))]
13070   "TARGET_80387 || TARGET_SSE_MATH"
13071   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13073 (define_expand "bltgt"
13074   [(set (pc)
13075         (if_then_else (match_dup 1)
13076                       (label_ref (match_operand 0 "" ""))
13077                       (pc)))]
13078   "TARGET_80387 || TARGET_SSE_MATH"
13079   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13081 (define_insn "*jcc_1"
13082   [(set (pc)
13083         (if_then_else (match_operator 1 "ix86_comparison_operator"
13084                                       [(reg FLAGS_REG) (const_int 0)])
13085                       (label_ref (match_operand 0 "" ""))
13086                       (pc)))]
13087   ""
13088   "%+j%C1\t%l0"
13089   [(set_attr "type" "ibr")
13090    (set_attr "modrm" "0")
13091    (set (attr "length")
13092            (if_then_else (and (ge (minus (match_dup 0) (pc))
13093                                   (const_int -126))
13094                               (lt (minus (match_dup 0) (pc))
13095                                   (const_int 128)))
13096              (const_int 2)
13097              (const_int 6)))])
13099 (define_insn "*jcc_2"
13100   [(set (pc)
13101         (if_then_else (match_operator 1 "ix86_comparison_operator"
13102                                       [(reg FLAGS_REG) (const_int 0)])
13103                       (pc)
13104                       (label_ref (match_operand 0 "" ""))))]
13105   ""
13106   "%+j%c1\t%l0"
13107   [(set_attr "type" "ibr")
13108    (set_attr "modrm" "0")
13109    (set (attr "length")
13110            (if_then_else (and (ge (minus (match_dup 0) (pc))
13111                                   (const_int -126))
13112                               (lt (minus (match_dup 0) (pc))
13113                                   (const_int 128)))
13114              (const_int 2)
13115              (const_int 6)))])
13117 ;; In general it is not safe to assume too much about CCmode registers,
13118 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13119 ;; conditions this is safe on x86, so help combine not create
13121 ;;      seta    %al
13122 ;;      testb   %al, %al
13123 ;;      je      Lfoo
13125 (define_split 
13126   [(set (pc)
13127         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13128                                       [(reg FLAGS_REG) (const_int 0)])
13129                           (const_int 0))
13130                       (label_ref (match_operand 1 "" ""))
13131                       (pc)))]
13132   ""
13133   [(set (pc)
13134         (if_then_else (match_dup 0)
13135                       (label_ref (match_dup 1))
13136                       (pc)))]
13138   PUT_MODE (operands[0], VOIDmode);
13140   
13141 (define_split 
13142   [(set (pc)
13143         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13144                                       [(reg FLAGS_REG) (const_int 0)])
13145                           (const_int 0))
13146                       (label_ref (match_operand 1 "" ""))
13147                       (pc)))]
13148   ""
13149   [(set (pc)
13150         (if_then_else (match_dup 0)
13151                       (label_ref (match_dup 1))
13152                       (pc)))]
13154   rtx new_op0 = copy_rtx (operands[0]);
13155   operands[0] = new_op0;
13156   PUT_MODE (new_op0, VOIDmode);
13157   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13158                                              GET_MODE (XEXP (new_op0, 0))));
13160   /* Make sure that (a) the CCmode we have for the flags is strong
13161      enough for the reversed compare or (b) we have a valid FP compare.  */
13162   if (! ix86_comparison_operator (new_op0, VOIDmode))
13163     FAIL;
13166 ;; Define combination compare-and-branch fp compare instructions to use
13167 ;; during early optimization.  Splitting the operation apart early makes
13168 ;; for bad code when we want to reverse the operation.
13170 (define_insn "*fp_jcc_1_mixed"
13171   [(set (pc)
13172         (if_then_else (match_operator 0 "comparison_operator"
13173                         [(match_operand 1 "register_operand" "f,x")
13174                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13175           (label_ref (match_operand 3 "" ""))
13176           (pc)))
13177    (clobber (reg:CCFP FPSR_REG))
13178    (clobber (reg:CCFP FLAGS_REG))]
13179   "TARGET_MIX_SSE_I387
13180    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13181    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13182    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13183   "#")
13185 (define_insn "*fp_jcc_1_sse"
13186   [(set (pc)
13187         (if_then_else (match_operator 0 "comparison_operator"
13188                         [(match_operand 1 "register_operand" "x")
13189                          (match_operand 2 "nonimmediate_operand" "xm")])
13190           (label_ref (match_operand 3 "" ""))
13191           (pc)))
13192    (clobber (reg:CCFP FPSR_REG))
13193    (clobber (reg:CCFP FLAGS_REG))]
13194   "TARGET_SSE_MATH
13195    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13196    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13197    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13198   "#")
13200 (define_insn "*fp_jcc_1_387"
13201   [(set (pc)
13202         (if_then_else (match_operator 0 "comparison_operator"
13203                         [(match_operand 1 "register_operand" "f")
13204                          (match_operand 2 "register_operand" "f")])
13205           (label_ref (match_operand 3 "" ""))
13206           (pc)))
13207    (clobber (reg:CCFP FPSR_REG))
13208    (clobber (reg:CCFP FLAGS_REG))]
13209   "TARGET_CMOVE && TARGET_80387
13210    && FLOAT_MODE_P (GET_MODE (operands[1]))
13211    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13212    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13213   "#")
13215 (define_insn "*fp_jcc_2_mixed"
13216   [(set (pc)
13217         (if_then_else (match_operator 0 "comparison_operator"
13218                         [(match_operand 1 "register_operand" "f,x")
13219                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13220           (pc)
13221           (label_ref (match_operand 3 "" ""))))
13222    (clobber (reg:CCFP FPSR_REG))
13223    (clobber (reg:CCFP FLAGS_REG))]
13224   "TARGET_MIX_SSE_I387
13225    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13226    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13227    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13228   "#")
13230 (define_insn "*fp_jcc_2_sse"
13231   [(set (pc)
13232         (if_then_else (match_operator 0 "comparison_operator"
13233                         [(match_operand 1 "register_operand" "x")
13234                          (match_operand 2 "nonimmediate_operand" "xm")])
13235           (pc)
13236           (label_ref (match_operand 3 "" ""))))
13237    (clobber (reg:CCFP FPSR_REG))
13238    (clobber (reg:CCFP FLAGS_REG))]
13239   "TARGET_SSE_MATH
13240    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13241    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13243   "#")
13245 (define_insn "*fp_jcc_2_387"
13246   [(set (pc)
13247         (if_then_else (match_operator 0 "comparison_operator"
13248                         [(match_operand 1 "register_operand" "f")
13249                          (match_operand 2 "register_operand" "f")])
13250           (pc)
13251           (label_ref (match_operand 3 "" ""))))
13252    (clobber (reg:CCFP FPSR_REG))
13253    (clobber (reg:CCFP FLAGS_REG))]
13254   "TARGET_CMOVE && TARGET_80387
13255    && FLOAT_MODE_P (GET_MODE (operands[1]))
13256    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13257    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13258   "#")
13260 (define_insn "*fp_jcc_3_387"
13261   [(set (pc)
13262         (if_then_else (match_operator 0 "comparison_operator"
13263                         [(match_operand 1 "register_operand" "f")
13264                          (match_operand 2 "nonimmediate_operand" "fm")])
13265           (label_ref (match_operand 3 "" ""))
13266           (pc)))
13267    (clobber (reg:CCFP FPSR_REG))
13268    (clobber (reg:CCFP FLAGS_REG))
13269    (clobber (match_scratch:HI 4 "=a"))]
13270   "TARGET_80387
13271    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13272    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13273    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13274    && SELECT_CC_MODE (GET_CODE (operands[0]),
13275                       operands[1], operands[2]) == CCFPmode
13276    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13277   "#")
13279 (define_insn "*fp_jcc_4_387"
13280   [(set (pc)
13281         (if_then_else (match_operator 0 "comparison_operator"
13282                         [(match_operand 1 "register_operand" "f")
13283                          (match_operand 2 "nonimmediate_operand" "fm")])
13284           (pc)
13285           (label_ref (match_operand 3 "" ""))))
13286    (clobber (reg:CCFP FPSR_REG))
13287    (clobber (reg:CCFP FLAGS_REG))
13288    (clobber (match_scratch:HI 4 "=a"))]
13289   "TARGET_80387
13290    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13291    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13292    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13293    && SELECT_CC_MODE (GET_CODE (operands[0]),
13294                       operands[1], operands[2]) == CCFPmode
13295    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13296   "#")
13298 (define_insn "*fp_jcc_5_387"
13299   [(set (pc)
13300         (if_then_else (match_operator 0 "comparison_operator"
13301                         [(match_operand 1 "register_operand" "f")
13302                          (match_operand 2 "register_operand" "f")])
13303           (label_ref (match_operand 3 "" ""))
13304           (pc)))
13305    (clobber (reg:CCFP FPSR_REG))
13306    (clobber (reg:CCFP FLAGS_REG))
13307    (clobber (match_scratch:HI 4 "=a"))]
13308   "TARGET_80387
13309    && FLOAT_MODE_P (GET_MODE (operands[1]))
13310    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13311    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13312   "#")
13314 (define_insn "*fp_jcc_6_387"
13315   [(set (pc)
13316         (if_then_else (match_operator 0 "comparison_operator"
13317                         [(match_operand 1 "register_operand" "f")
13318                          (match_operand 2 "register_operand" "f")])
13319           (pc)
13320           (label_ref (match_operand 3 "" ""))))
13321    (clobber (reg:CCFP FPSR_REG))
13322    (clobber (reg:CCFP FLAGS_REG))
13323    (clobber (match_scratch:HI 4 "=a"))]
13324   "TARGET_80387
13325    && FLOAT_MODE_P (GET_MODE (operands[1]))
13326    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13327    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13328   "#")
13330 (define_insn "*fp_jcc_7_387"
13331   [(set (pc)
13332         (if_then_else (match_operator 0 "comparison_operator"
13333                         [(match_operand 1 "register_operand" "f")
13334                          (match_operand 2 "const0_operand" "X")])
13335           (label_ref (match_operand 3 "" ""))
13336           (pc)))
13337    (clobber (reg:CCFP FPSR_REG))
13338    (clobber (reg:CCFP FLAGS_REG))
13339    (clobber (match_scratch:HI 4 "=a"))]
13340   "TARGET_80387
13341    && FLOAT_MODE_P (GET_MODE (operands[1]))
13342    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13343    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13344    && SELECT_CC_MODE (GET_CODE (operands[0]),
13345                       operands[1], operands[2]) == CCFPmode
13346    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13347   "#")
13349 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13350 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13351 ;; with a precedence over other operators and is always put in the first
13352 ;; place. Swap condition and operands to match ficom instruction.
13354 (define_insn "*fp_jcc_8<mode>_387"
13355   [(set (pc)
13356         (if_then_else (match_operator 0 "comparison_operator"
13357                         [(match_operator 1 "float_operator"
13358                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13359                            (match_operand 3 "register_operand" "f,f")])
13360           (label_ref (match_operand 4 "" ""))
13361           (pc)))
13362    (clobber (reg:CCFP FPSR_REG))
13363    (clobber (reg:CCFP FLAGS_REG))
13364    (clobber (match_scratch:HI 5 "=a,a"))]
13365   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13366    && FLOAT_MODE_P (GET_MODE (operands[3]))
13367    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13368    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13369    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13370    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13371   "#")
13373 (define_split
13374   [(set (pc)
13375         (if_then_else (match_operator 0 "comparison_operator"
13376                         [(match_operand 1 "register_operand" "")
13377                          (match_operand 2 "nonimmediate_operand" "")])
13378           (match_operand 3 "" "")
13379           (match_operand 4 "" "")))
13380    (clobber (reg:CCFP FPSR_REG))
13381    (clobber (reg:CCFP FLAGS_REG))]
13382   "reload_completed"
13383   [(const_int 0)]
13385   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13386                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13387   DONE;
13390 (define_split
13391   [(set (pc)
13392         (if_then_else (match_operator 0 "comparison_operator"
13393                         [(match_operand 1 "register_operand" "")
13394                          (match_operand 2 "general_operand" "")])
13395           (match_operand 3 "" "")
13396           (match_operand 4 "" "")))
13397    (clobber (reg:CCFP FPSR_REG))
13398    (clobber (reg:CCFP FLAGS_REG))
13399    (clobber (match_scratch:HI 5 "=a"))]
13400   "reload_completed"
13401   [(const_int 0)]
13403   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13404                         operands[3], operands[4], operands[5], NULL_RTX);
13405   DONE;
13408 (define_split
13409   [(set (pc)
13410         (if_then_else (match_operator 0 "comparison_operator"
13411                         [(match_operator 1 "float_operator"
13412                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13413                            (match_operand 3 "register_operand" "")])
13414           (match_operand 4 "" "")
13415           (match_operand 5 "" "")))
13416    (clobber (reg:CCFP FPSR_REG))
13417    (clobber (reg:CCFP FLAGS_REG))
13418    (clobber (match_scratch:HI 6 "=a"))]
13419   "reload_completed"
13420   [(const_int 0)]
13422   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13423   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13424                         operands[3], operands[7],
13425                         operands[4], operands[5], operands[6], NULL_RTX);
13426   DONE;
13429 ;; %%% Kill this when reload knows how to do it.
13430 (define_split
13431   [(set (pc)
13432         (if_then_else (match_operator 0 "comparison_operator"
13433                         [(match_operator 1 "float_operator"
13434                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13435                            (match_operand 3 "register_operand" "")])
13436           (match_operand 4 "" "")
13437           (match_operand 5 "" "")))
13438    (clobber (reg:CCFP FPSR_REG))
13439    (clobber (reg:CCFP FLAGS_REG))
13440    (clobber (match_scratch:HI 6 "=a"))]
13441   "reload_completed"
13442   [(const_int 0)]
13444   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13445   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13446   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13447                         operands[3], operands[7],
13448                         operands[4], operands[5], operands[6], operands[2]);
13449   DONE;
13452 ;; Unconditional and other jump instructions
13454 (define_insn "jump"
13455   [(set (pc)
13456         (label_ref (match_operand 0 "" "")))]
13457   ""
13458   "jmp\t%l0"
13459   [(set_attr "type" "ibr")
13460    (set (attr "length")
13461            (if_then_else (and (ge (minus (match_dup 0) (pc))
13462                                   (const_int -126))
13463                               (lt (minus (match_dup 0) (pc))
13464                                   (const_int 128)))
13465              (const_int 2)
13466              (const_int 5)))
13467    (set_attr "modrm" "0")])
13469 (define_expand "indirect_jump"
13470   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13471   ""
13472   "")
13474 (define_insn "*indirect_jump"
13475   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13476   "!TARGET_64BIT"
13477   "jmp\t%A0"
13478   [(set_attr "type" "ibr")
13479    (set_attr "length_immediate" "0")])
13481 (define_insn "*indirect_jump_rtx64"
13482   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13483   "TARGET_64BIT"
13484   "jmp\t%A0"
13485   [(set_attr "type" "ibr")
13486    (set_attr "length_immediate" "0")])
13488 (define_expand "tablejump"
13489   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13490               (use (label_ref (match_operand 1 "" "")))])]
13491   ""
13493   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13494      relative.  Convert the relative address to an absolute address.  */
13495   if (flag_pic)
13496     {
13497       rtx op0, op1;
13498       enum rtx_code code;
13500       if (TARGET_64BIT)
13501         {
13502           code = PLUS;
13503           op0 = operands[0];
13504           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13505         }
13506       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13507         {
13508           code = PLUS;
13509           op0 = operands[0];
13510           op1 = pic_offset_table_rtx;
13511         }
13512       else
13513         {
13514           code = MINUS;
13515           op0 = pic_offset_table_rtx;
13516           op1 = operands[0];
13517         }
13519       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13520                                          OPTAB_DIRECT);
13521     }
13524 (define_insn "*tablejump_1"
13525   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13526    (use (label_ref (match_operand 1 "" "")))]
13527   "!TARGET_64BIT"
13528   "jmp\t%A0"
13529   [(set_attr "type" "ibr")
13530    (set_attr "length_immediate" "0")])
13532 (define_insn "*tablejump_1_rtx64"
13533   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13534    (use (label_ref (match_operand 1 "" "")))]
13535   "TARGET_64BIT"
13536   "jmp\t%A0"
13537   [(set_attr "type" "ibr")
13538    (set_attr "length_immediate" "0")])
13540 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13542 (define_peephole2
13543   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13544    (set (match_operand:QI 1 "register_operand" "")
13545         (match_operator:QI 2 "ix86_comparison_operator"
13546           [(reg FLAGS_REG) (const_int 0)]))
13547    (set (match_operand 3 "q_regs_operand" "")
13548         (zero_extend (match_dup 1)))]
13549   "(peep2_reg_dead_p (3, operands[1])
13550     || operands_match_p (operands[1], operands[3]))
13551    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13552   [(set (match_dup 4) (match_dup 0))
13553    (set (strict_low_part (match_dup 5))
13554         (match_dup 2))]
13556   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13557   operands[5] = gen_lowpart (QImode, operands[3]);
13558   ix86_expand_clear (operands[3]);
13561 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13563 (define_peephole2
13564   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13565    (set (match_operand:QI 1 "register_operand" "")
13566         (match_operator:QI 2 "ix86_comparison_operator"
13567           [(reg FLAGS_REG) (const_int 0)]))
13568    (parallel [(set (match_operand 3 "q_regs_operand" "")
13569                    (zero_extend (match_dup 1)))
13570               (clobber (reg:CC FLAGS_REG))])]
13571   "(peep2_reg_dead_p (3, operands[1])
13572     || operands_match_p (operands[1], operands[3]))
13573    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13574   [(set (match_dup 4) (match_dup 0))
13575    (set (strict_low_part (match_dup 5))
13576         (match_dup 2))]
13578   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13579   operands[5] = gen_lowpart (QImode, operands[3]);
13580   ix86_expand_clear (operands[3]);
13583 ;; Call instructions.
13585 ;; The predicates normally associated with named expanders are not properly
13586 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13587 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13589 ;; Call subroutine returning no value.
13591 (define_expand "call_pop"
13592   [(parallel [(call (match_operand:QI 0 "" "")
13593                     (match_operand:SI 1 "" ""))
13594               (set (reg:SI SP_REG)
13595                    (plus:SI (reg:SI SP_REG)
13596                             (match_operand:SI 3 "" "")))])]
13597   "!TARGET_64BIT"
13599   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13600   DONE;
13603 (define_insn "*call_pop_0"
13604   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13605          (match_operand:SI 1 "" ""))
13606    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13607                             (match_operand:SI 2 "immediate_operand" "")))]
13608   "!TARGET_64BIT"
13610   if (SIBLING_CALL_P (insn))
13611     return "jmp\t%P0";
13612   else
13613     return "call\t%P0";
13615   [(set_attr "type" "call")])
13616   
13617 (define_insn "*call_pop_1"
13618   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13619          (match_operand:SI 1 "" ""))
13620    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13621                             (match_operand:SI 2 "immediate_operand" "i")))]
13622   "!TARGET_64BIT"
13624   if (constant_call_address_operand (operands[0], Pmode))
13625     {
13626       if (SIBLING_CALL_P (insn))
13627         return "jmp\t%P0";
13628       else
13629         return "call\t%P0";
13630     }
13631   if (SIBLING_CALL_P (insn))
13632     return "jmp\t%A0";
13633   else
13634     return "call\t%A0";
13636   [(set_attr "type" "call")])
13638 (define_expand "call"
13639   [(call (match_operand:QI 0 "" "")
13640          (match_operand 1 "" ""))
13641    (use (match_operand 2 "" ""))]
13642   ""
13644   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13645   DONE;
13648 (define_expand "sibcall"
13649   [(call (match_operand:QI 0 "" "")
13650          (match_operand 1 "" ""))
13651    (use (match_operand 2 "" ""))]
13652   ""
13654   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13655   DONE;
13658 (define_insn "*call_0"
13659   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13660          (match_operand 1 "" ""))]
13661   ""
13663   if (SIBLING_CALL_P (insn))
13664     return "jmp\t%P0";
13665   else
13666     return "call\t%P0";
13668   [(set_attr "type" "call")])
13670 (define_insn "*call_1"
13671   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13672          (match_operand 1 "" ""))]
13673   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13675   if (constant_call_address_operand (operands[0], Pmode))
13676     return "call\t%P0";
13677   return "call\t%A0";
13679   [(set_attr "type" "call")])
13681 (define_insn "*sibcall_1"
13682   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13683          (match_operand 1 "" ""))]
13684   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13686   if (constant_call_address_operand (operands[0], Pmode))
13687     return "jmp\t%P0";
13688   return "jmp\t%A0";
13690   [(set_attr "type" "call")])
13692 (define_insn "*call_1_rex64"
13693   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13694          (match_operand 1 "" ""))]
13695   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13697   if (constant_call_address_operand (operands[0], Pmode))
13698     return "call\t%P0";
13699   return "call\t%A0";
13701   [(set_attr "type" "call")])
13703 (define_insn "*sibcall_1_rex64"
13704   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13705          (match_operand 1 "" ""))]
13706   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13707   "jmp\t%P0"
13708   [(set_attr "type" "call")])
13710 (define_insn "*sibcall_1_rex64_v"
13711   [(call (mem:QI (reg:DI 40))
13712          (match_operand 0 "" ""))]
13713   "SIBLING_CALL_P (insn) && TARGET_64BIT"
13714   "jmp\t*%%r11"
13715   [(set_attr "type" "call")])
13718 ;; Call subroutine, returning value in operand 0
13720 (define_expand "call_value_pop"
13721   [(parallel [(set (match_operand 0 "" "")
13722                    (call (match_operand:QI 1 "" "")
13723                          (match_operand:SI 2 "" "")))
13724               (set (reg:SI SP_REG)
13725                    (plus:SI (reg:SI SP_REG)
13726                             (match_operand:SI 4 "" "")))])]
13727   "!TARGET_64BIT"
13729   ix86_expand_call (operands[0], operands[1], operands[2],
13730                     operands[3], operands[4], 0);
13731   DONE;
13734 (define_expand "call_value"
13735   [(set (match_operand 0 "" "")
13736         (call (match_operand:QI 1 "" "")
13737               (match_operand:SI 2 "" "")))
13738    (use (match_operand:SI 3 "" ""))]
13739   ;; Operand 2 not used on the i386.
13740   ""
13742   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13743   DONE;
13746 (define_expand "sibcall_value"
13747   [(set (match_operand 0 "" "")
13748         (call (match_operand:QI 1 "" "")
13749               (match_operand:SI 2 "" "")))
13750    (use (match_operand:SI 3 "" ""))]
13751   ;; Operand 2 not used on the i386.
13752   ""
13754   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13755   DONE;
13758 ;; Call subroutine returning any type.
13760 (define_expand "untyped_call"
13761   [(parallel [(call (match_operand 0 "" "")
13762                     (const_int 0))
13763               (match_operand 1 "" "")
13764               (match_operand 2 "" "")])]
13765   ""
13767   int i;
13769   /* In order to give reg-stack an easier job in validating two
13770      coprocessor registers as containing a possible return value,
13771      simply pretend the untyped call returns a complex long double
13772      value.  */
13774   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13775                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13776                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13777                     NULL, 0);
13779   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13780     {
13781       rtx set = XVECEXP (operands[2], 0, i);
13782       emit_move_insn (SET_DEST (set), SET_SRC (set));
13783     }
13785   /* The optimizer does not know that the call sets the function value
13786      registers we stored in the result block.  We avoid problems by
13787      claiming that all hard registers are used and clobbered at this
13788      point.  */
13789   emit_insn (gen_blockage (const0_rtx));
13791   DONE;
13794 ;; Prologue and epilogue instructions
13796 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13797 ;; all of memory.  This blocks insns from being moved across this point.
13799 (define_insn "blockage"
13800   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13801   ""
13802   ""
13803   [(set_attr "length" "0")])
13805 ;; Insn emitted into the body of a function to return from a function.
13806 ;; This is only done if the function's epilogue is known to be simple.
13807 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13809 (define_expand "return"
13810   [(return)]
13811   "ix86_can_use_return_insn_p ()"
13813   if (current_function_pops_args)
13814     {
13815       rtx popc = GEN_INT (current_function_pops_args);
13816       emit_jump_insn (gen_return_pop_internal (popc));
13817       DONE;
13818     }
13821 (define_insn "return_internal"
13822   [(return)]
13823   "reload_completed"
13824   "ret"
13825   [(set_attr "length" "1")
13826    (set_attr "length_immediate" "0")
13827    (set_attr "modrm" "0")])
13829 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13830 ;; instruction Athlon and K8 have.
13832 (define_insn "return_internal_long"
13833   [(return)
13834    (unspec [(const_int 0)] UNSPEC_REP)]
13835   "reload_completed"
13836   "rep {;} ret"
13837   [(set_attr "length" "1")
13838    (set_attr "length_immediate" "0")
13839    (set_attr "prefix_rep" "1")
13840    (set_attr "modrm" "0")])
13842 (define_insn "return_pop_internal"
13843   [(return)
13844    (use (match_operand:SI 0 "const_int_operand" ""))]
13845   "reload_completed"
13846   "ret\t%0"
13847   [(set_attr "length" "3")
13848    (set_attr "length_immediate" "2")
13849    (set_attr "modrm" "0")])
13851 (define_insn "return_indirect_internal"
13852   [(return)
13853    (use (match_operand:SI 0 "register_operand" "r"))]
13854   "reload_completed"
13855   "jmp\t%A0"
13856   [(set_attr "type" "ibr")
13857    (set_attr "length_immediate" "0")])
13859 (define_insn "nop"
13860   [(const_int 0)]
13861   ""
13862   "nop"
13863   [(set_attr "length" "1")
13864    (set_attr "length_immediate" "0")
13865    (set_attr "modrm" "0")])
13867 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
13868 ;; branch prediction penalty for the third jump in a 16-byte
13869 ;; block on K8.
13871 (define_insn "align"
13872   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13873   ""
13875 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13876   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13877 #else
13878   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13879      The align insn is used to avoid 3 jump instructions in the row to improve
13880      branch prediction and the benefits hardly outweigh the cost of extra 8
13881      nops on the average inserted by full alignment pseudo operation.  */
13882 #endif
13883   return "";
13885   [(set_attr "length" "16")])
13887 (define_expand "prologue"
13888   [(const_int 1)]
13889   ""
13890   "ix86_expand_prologue (); DONE;")
13892 (define_insn "set_got"
13893   [(set (match_operand:SI 0 "register_operand" "=r")
13894         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13895    (clobber (reg:CC FLAGS_REG))]
13896   "!TARGET_64BIT"
13897   { return output_set_got (operands[0], NULL_RTX); }
13898   [(set_attr "type" "multi")
13899    (set_attr "length" "12")])
13901 (define_insn "set_got_labelled"
13902   [(set (match_operand:SI 0 "register_operand" "=r")
13903         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13904          UNSPEC_SET_GOT))
13905    (clobber (reg:CC FLAGS_REG))]
13906   "!TARGET_64BIT"
13907   { return output_set_got (operands[0], operands[1]); }
13908   [(set_attr "type" "multi")
13909    (set_attr "length" "12")])
13911 (define_insn "set_got_rex64"
13912   [(set (match_operand:DI 0 "register_operand" "=r")
13913         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13914   "TARGET_64BIT"
13915   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13916   [(set_attr "type" "lea")
13917    (set_attr "length" "6")])
13919 (define_expand "epilogue"
13920   [(const_int 1)]
13921   ""
13922   "ix86_expand_epilogue (1); DONE;")
13924 (define_expand "sibcall_epilogue"
13925   [(const_int 1)]
13926   ""
13927   "ix86_expand_epilogue (0); DONE;")
13929 (define_expand "eh_return"
13930   [(use (match_operand 0 "register_operand" ""))]
13931   ""
13933   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13935   /* Tricky bit: we write the address of the handler to which we will
13936      be returning into someone else's stack frame, one word below the
13937      stack address we wish to restore.  */
13938   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13939   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13940   tmp = gen_rtx_MEM (Pmode, tmp);
13941   emit_move_insn (tmp, ra);
13943   if (Pmode == SImode)
13944     emit_jump_insn (gen_eh_return_si (sa));
13945   else
13946     emit_jump_insn (gen_eh_return_di (sa));
13947   emit_barrier ();
13948   DONE;
13951 (define_insn_and_split "eh_return_si"
13952   [(set (pc) 
13953         (unspec [(match_operand:SI 0 "register_operand" "c")]
13954                  UNSPEC_EH_RETURN))]
13955   "!TARGET_64BIT"
13956   "#"
13957   "reload_completed"
13958   [(const_int 1)]
13959   "ix86_expand_epilogue (2); DONE;")
13961 (define_insn_and_split "eh_return_di"
13962   [(set (pc) 
13963         (unspec [(match_operand:DI 0 "register_operand" "c")]
13964                  UNSPEC_EH_RETURN))]
13965   "TARGET_64BIT"
13966   "#"
13967   "reload_completed"
13968   [(const_int 1)]
13969   "ix86_expand_epilogue (2); DONE;")
13971 (define_insn "leave"
13972   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13973    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13974    (clobber (mem:BLK (scratch)))]
13975   "!TARGET_64BIT"
13976   "leave"
13977   [(set_attr "type" "leave")])
13979 (define_insn "leave_rex64"
13980   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13981    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13982    (clobber (mem:BLK (scratch)))]
13983   "TARGET_64BIT"
13984   "leave"
13985   [(set_attr "type" "leave")])
13987 (define_expand "ffssi2"
13988   [(parallel
13989      [(set (match_operand:SI 0 "register_operand" "") 
13990            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13991       (clobber (match_scratch:SI 2 ""))
13992       (clobber (reg:CC FLAGS_REG))])]
13993   ""
13994   "")
13996 (define_insn_and_split "*ffs_cmove"
13997   [(set (match_operand:SI 0 "register_operand" "=r") 
13998         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13999    (clobber (match_scratch:SI 2 "=&r"))
14000    (clobber (reg:CC FLAGS_REG))]
14001   "TARGET_CMOVE"
14002   "#"
14003   "&& reload_completed"
14004   [(set (match_dup 2) (const_int -1))
14005    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14006               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14007    (set (match_dup 0) (if_then_else:SI
14008                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14009                         (match_dup 2)
14010                         (match_dup 0)))
14011    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14012               (clobber (reg:CC FLAGS_REG))])]
14013   "")
14015 (define_insn_and_split "*ffs_no_cmove"
14016   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14017         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14018    (clobber (match_scratch:SI 2 "=&q"))
14019    (clobber (reg:CC FLAGS_REG))]
14020   ""
14021   "#"
14022   "reload_completed"
14023   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14024               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14025    (set (strict_low_part (match_dup 3))
14026         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14027    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14028               (clobber (reg:CC FLAGS_REG))])
14029    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14030               (clobber (reg:CC FLAGS_REG))])
14031    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14032               (clobber (reg:CC FLAGS_REG))])]
14034   operands[3] = gen_lowpart (QImode, operands[2]);
14035   ix86_expand_clear (operands[2]);
14038 (define_insn "*ffssi_1"
14039   [(set (reg:CCZ FLAGS_REG)
14040         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14041                      (const_int 0)))
14042    (set (match_operand:SI 0 "register_operand" "=r")
14043         (ctz:SI (match_dup 1)))]
14044   ""
14045   "bsf{l}\t{%1, %0|%0, %1}"
14046   [(set_attr "prefix_0f" "1")])
14048 (define_expand "ffsdi2"
14049   [(parallel
14050      [(set (match_operand:DI 0 "register_operand" "") 
14051            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14052       (clobber (match_scratch:DI 2 ""))
14053       (clobber (reg:CC FLAGS_REG))])]
14054   "TARGET_64BIT && TARGET_CMOVE"
14055   "")
14057 (define_insn_and_split "*ffs_rex64"
14058   [(set (match_operand:DI 0 "register_operand" "=r") 
14059         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14060    (clobber (match_scratch:DI 2 "=&r"))
14061    (clobber (reg:CC FLAGS_REG))]
14062   "TARGET_64BIT && TARGET_CMOVE"
14063   "#"
14064   "&& reload_completed"
14065   [(set (match_dup 2) (const_int -1))
14066    (parallel [(set (reg:CCZ FLAGS_REG)
14067                    (compare:CCZ (match_dup 1) (const_int 0)))
14068               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14069    (set (match_dup 0) (if_then_else:DI
14070                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14071                         (match_dup 2)
14072                         (match_dup 0)))
14073    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14074               (clobber (reg:CC FLAGS_REG))])]
14075   "")
14077 (define_insn "*ffsdi_1"
14078   [(set (reg:CCZ FLAGS_REG)
14079         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14080                      (const_int 0)))
14081    (set (match_operand:DI 0 "register_operand" "=r")
14082         (ctz:DI (match_dup 1)))]
14083   "TARGET_64BIT"
14084   "bsf{q}\t{%1, %0|%0, %1}"
14085   [(set_attr "prefix_0f" "1")])
14087 (define_insn "ctzsi2"
14088   [(set (match_operand:SI 0 "register_operand" "=r")
14089         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14090    (clobber (reg:CC FLAGS_REG))]
14091   ""
14092   "bsf{l}\t{%1, %0|%0, %1}"
14093   [(set_attr "prefix_0f" "1")])
14095 (define_insn "ctzdi2"
14096   [(set (match_operand:DI 0 "register_operand" "=r")
14097         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14098    (clobber (reg:CC FLAGS_REG))]
14099   "TARGET_64BIT"
14100   "bsf{q}\t{%1, %0|%0, %1}"
14101   [(set_attr "prefix_0f" "1")])
14103 (define_expand "clzsi2"
14104   [(parallel
14105      [(set (match_operand:SI 0 "register_operand" "")
14106            (minus:SI (const_int 31)
14107                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14108       (clobber (reg:CC FLAGS_REG))])
14109    (parallel
14110      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14111       (clobber (reg:CC FLAGS_REG))])]
14112   ""
14113   "")
14115 (define_insn "*bsr"
14116   [(set (match_operand:SI 0 "register_operand" "=r")
14117         (minus:SI (const_int 31)
14118                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14119    (clobber (reg:CC FLAGS_REG))]
14120   ""
14121   "bsr{l}\t{%1, %0|%0, %1}"
14122   [(set_attr "prefix_0f" "1")])
14124 (define_expand "clzdi2"
14125   [(parallel
14126      [(set (match_operand:DI 0 "register_operand" "")
14127            (minus:DI (const_int 63)
14128                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14129       (clobber (reg:CC FLAGS_REG))])
14130    (parallel
14131      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14132       (clobber (reg:CC FLAGS_REG))])]
14133   "TARGET_64BIT"
14134   "")
14136 (define_insn "*bsr_rex64"
14137   [(set (match_operand:DI 0 "register_operand" "=r")
14138         (minus:DI (const_int 63)
14139                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14140    (clobber (reg:CC FLAGS_REG))]
14141   "TARGET_64BIT"
14142   "bsr{q}\t{%1, %0|%0, %1}"
14143   [(set_attr "prefix_0f" "1")])
14145 ;; Thread-local storage patterns for ELF.
14147 ;; Note that these code sequences must appear exactly as shown
14148 ;; in order to allow linker relaxation.
14150 (define_insn "*tls_global_dynamic_32_gnu"
14151   [(set (match_operand:SI 0 "register_operand" "=a")
14152         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14153                     (match_operand:SI 2 "tls_symbolic_operand" "")
14154                     (match_operand:SI 3 "call_insn_operand" "")]
14155                     UNSPEC_TLS_GD))
14156    (clobber (match_scratch:SI 4 "=d"))
14157    (clobber (match_scratch:SI 5 "=c"))
14158    (clobber (reg:CC FLAGS_REG))]
14159   "!TARGET_64BIT && TARGET_GNU_TLS"
14160   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14161   [(set_attr "type" "multi")
14162    (set_attr "length" "12")])
14164 (define_insn "*tls_global_dynamic_32_sun"
14165   [(set (match_operand:SI 0 "register_operand" "=a")
14166         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14167                     (match_operand:SI 2 "tls_symbolic_operand" "")
14168                     (match_operand:SI 3 "call_insn_operand" "")]
14169                     UNSPEC_TLS_GD))
14170    (clobber (match_scratch:SI 4 "=d"))
14171    (clobber (match_scratch:SI 5 "=c"))
14172    (clobber (reg:CC FLAGS_REG))]
14173   "!TARGET_64BIT && TARGET_SUN_TLS"
14174   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14175         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14176   [(set_attr "type" "multi")
14177    (set_attr "length" "14")])
14179 (define_expand "tls_global_dynamic_32"
14180   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14181                    (unspec:SI
14182                     [(match_dup 2)
14183                      (match_operand:SI 1 "tls_symbolic_operand" "")
14184                      (match_dup 3)]
14185                     UNSPEC_TLS_GD))
14186               (clobber (match_scratch:SI 4 ""))
14187               (clobber (match_scratch:SI 5 ""))
14188               (clobber (reg:CC FLAGS_REG))])]
14189   ""
14191   if (flag_pic)
14192     operands[2] = pic_offset_table_rtx;
14193   else
14194     {
14195       operands[2] = gen_reg_rtx (Pmode);
14196       emit_insn (gen_set_got (operands[2]));
14197     }
14198   if (TARGET_GNU2_TLS)
14199     {
14200        emit_insn (gen_tls_dynamic_gnu2_32
14201                   (operands[0], operands[1], operands[2]));
14202        DONE;
14203     }
14204   operands[3] = ix86_tls_get_addr ();
14207 (define_insn "*tls_global_dynamic_64"
14208   [(set (match_operand:DI 0 "register_operand" "=a")
14209         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14210                  (match_operand:DI 3 "" "")))
14211    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14212               UNSPEC_TLS_GD)]
14213   "TARGET_64BIT"
14214   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14215   [(set_attr "type" "multi")
14216    (set_attr "length" "16")])
14218 (define_expand "tls_global_dynamic_64"
14219   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14220                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14221               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14222                          UNSPEC_TLS_GD)])]
14223   ""
14225   if (TARGET_GNU2_TLS)
14226     {
14227        emit_insn (gen_tls_dynamic_gnu2_64
14228                   (operands[0], operands[1]));
14229        DONE;
14230     }
14231   operands[2] = ix86_tls_get_addr ();
14234 (define_insn "*tls_local_dynamic_base_32_gnu"
14235   [(set (match_operand:SI 0 "register_operand" "=a")
14236         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14237                     (match_operand:SI 2 "call_insn_operand" "")]
14238                    UNSPEC_TLS_LD_BASE))
14239    (clobber (match_scratch:SI 3 "=d"))
14240    (clobber (match_scratch:SI 4 "=c"))
14241    (clobber (reg:CC FLAGS_REG))]
14242   "!TARGET_64BIT && TARGET_GNU_TLS"
14243   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14244   [(set_attr "type" "multi")
14245    (set_attr "length" "11")])
14247 (define_insn "*tls_local_dynamic_base_32_sun"
14248   [(set (match_operand:SI 0 "register_operand" "=a")
14249         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14250                     (match_operand:SI 2 "call_insn_operand" "")]
14251                    UNSPEC_TLS_LD_BASE))
14252    (clobber (match_scratch:SI 3 "=d"))
14253    (clobber (match_scratch:SI 4 "=c"))
14254    (clobber (reg:CC FLAGS_REG))]
14255   "!TARGET_64BIT && TARGET_SUN_TLS"
14256   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14257         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14258   [(set_attr "type" "multi")
14259    (set_attr "length" "13")])
14261 (define_expand "tls_local_dynamic_base_32"
14262   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14263                    (unspec:SI [(match_dup 1) (match_dup 2)]
14264                               UNSPEC_TLS_LD_BASE))
14265               (clobber (match_scratch:SI 3 ""))
14266               (clobber (match_scratch:SI 4 ""))
14267               (clobber (reg:CC FLAGS_REG))])]
14268   ""
14270   if (flag_pic)
14271     operands[1] = pic_offset_table_rtx;
14272   else
14273     {
14274       operands[1] = gen_reg_rtx (Pmode);
14275       emit_insn (gen_set_got (operands[1]));
14276     }
14277   if (TARGET_GNU2_TLS)
14278     {
14279        emit_insn (gen_tls_dynamic_gnu2_32
14280                   (operands[0], ix86_tls_module_base (), operands[1]));
14281        DONE;
14282     }
14283   operands[2] = ix86_tls_get_addr ();
14286 (define_insn "*tls_local_dynamic_base_64"
14287   [(set (match_operand:DI 0 "register_operand" "=a")
14288         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14289                  (match_operand:DI 2 "" "")))
14290    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14291   "TARGET_64BIT"
14292   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14293   [(set_attr "type" "multi")
14294    (set_attr "length" "12")])
14296 (define_expand "tls_local_dynamic_base_64"
14297   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14298                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14299               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14300   ""
14302   if (TARGET_GNU2_TLS)
14303     {
14304        emit_insn (gen_tls_dynamic_gnu2_64
14305                   (operands[0], ix86_tls_module_base ()));
14306        DONE;
14307     }
14308   operands[1] = ix86_tls_get_addr ();
14311 ;; Local dynamic of a single variable is a lose.  Show combine how
14312 ;; to convert that back to global dynamic.
14314 (define_insn_and_split "*tls_local_dynamic_32_once"
14315   [(set (match_operand:SI 0 "register_operand" "=a")
14316         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14317                              (match_operand:SI 2 "call_insn_operand" "")]
14318                             UNSPEC_TLS_LD_BASE)
14319                  (const:SI (unspec:SI
14320                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14321                             UNSPEC_DTPOFF))))
14322    (clobber (match_scratch:SI 4 "=d"))
14323    (clobber (match_scratch:SI 5 "=c"))
14324    (clobber (reg:CC FLAGS_REG))]
14325   ""
14326   "#"
14327   ""
14328   [(parallel [(set (match_dup 0)
14329                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14330                               UNSPEC_TLS_GD))
14331               (clobber (match_dup 4))
14332               (clobber (match_dup 5))
14333               (clobber (reg:CC FLAGS_REG))])]
14334   "")
14336 ;; Load and add the thread base pointer from %gs:0.
14338 (define_insn "*load_tp_si"
14339   [(set (match_operand:SI 0 "register_operand" "=r")
14340         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14341   "!TARGET_64BIT"
14342   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14343   [(set_attr "type" "imov")
14344    (set_attr "modrm" "0")
14345    (set_attr "length" "7")
14346    (set_attr "memory" "load")
14347    (set_attr "imm_disp" "false")])
14349 (define_insn "*add_tp_si"
14350   [(set (match_operand:SI 0 "register_operand" "=r")
14351         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14352                  (match_operand:SI 1 "register_operand" "0")))
14353    (clobber (reg:CC FLAGS_REG))]
14354   "!TARGET_64BIT"
14355   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14356   [(set_attr "type" "alu")
14357    (set_attr "modrm" "0")
14358    (set_attr "length" "7")
14359    (set_attr "memory" "load")
14360    (set_attr "imm_disp" "false")])
14362 (define_insn "*load_tp_di"
14363   [(set (match_operand:DI 0 "register_operand" "=r")
14364         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14365   "TARGET_64BIT"
14366   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14367   [(set_attr "type" "imov")
14368    (set_attr "modrm" "0")
14369    (set_attr "length" "7")
14370    (set_attr "memory" "load")
14371    (set_attr "imm_disp" "false")])
14373 (define_insn "*add_tp_di"
14374   [(set (match_operand:DI 0 "register_operand" "=r")
14375         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14376                  (match_operand:DI 1 "register_operand" "0")))
14377    (clobber (reg:CC FLAGS_REG))]
14378   "TARGET_64BIT"
14379   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14380   [(set_attr "type" "alu")
14381    (set_attr "modrm" "0")
14382    (set_attr "length" "7")
14383    (set_attr "memory" "load")
14384    (set_attr "imm_disp" "false")])
14386 ;; GNU2 TLS patterns can be split.
14388 (define_expand "tls_dynamic_gnu2_32"
14389   [(set (match_dup 3)
14390         (plus:SI (match_operand:SI 2 "register_operand" "")
14391                  (const:SI
14392                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14393                              UNSPEC_TLSDESC))))
14394    (parallel
14395     [(set (match_operand:SI 0 "register_operand" "")
14396           (unspec:SI [(match_dup 1) (match_dup 3)
14397                       (match_dup 2) (reg:SI SP_REG)]
14398                       UNSPEC_TLSDESC))
14399      (clobber (reg:CC FLAGS_REG))])]
14400   "!TARGET_64BIT && TARGET_GNU2_TLS"
14402   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14403   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14406 (define_insn "*tls_dynamic_lea_32"
14407   [(set (match_operand:SI 0 "register_operand" "=r")
14408         (plus:SI (match_operand:SI 1 "register_operand" "b")
14409                  (const:SI
14410                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14411                               UNSPEC_TLSDESC))))]
14412   "!TARGET_64BIT && TARGET_GNU2_TLS"
14413   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14414   [(set_attr "type" "lea")
14415    (set_attr "mode" "SI")
14416    (set_attr "length" "6")
14417    (set_attr "length_address" "4")])
14419 (define_insn "*tls_dynamic_call_32"
14420   [(set (match_operand:SI 0 "register_operand" "=a")
14421         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14422                     (match_operand:SI 2 "register_operand" "0")
14423                     ;; we have to make sure %ebx still points to the GOT
14424                     (match_operand:SI 3 "register_operand" "b")
14425                     (reg:SI SP_REG)]
14426                    UNSPEC_TLSDESC))
14427    (clobber (reg:CC FLAGS_REG))]
14428   "!TARGET_64BIT && TARGET_GNU2_TLS"
14429   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14430   [(set_attr "type" "call")
14431    (set_attr "length" "2")
14432    (set_attr "length_address" "0")])
14434 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14435   [(set (match_operand:SI 0 "register_operand" "=&a")
14436         (plus:SI
14437          (plus:SI (match_operand:SI 3 "tp_or_register_operand" "ir")
14438                   (unspec:SI [(match_operand:SI 4 "tls_modbase_operand" "")
14439                               (match_operand:SI 5 "" "")
14440                               (match_operand:SI 2 "register_operand" "b")
14441                               (reg:SI SP_REG)]
14442                              UNSPEC_TLSDESC))
14443          (const:SI (unspec:SI
14444                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14445                     UNSPEC_DTPOFF))))
14446    (clobber (reg:CC FLAGS_REG))]
14447   "!TARGET_64BIT && TARGET_GNU2_TLS"
14448   "#"
14449   ""
14450   [(parallel
14451     [(set (match_dup 0)
14452           (plus:SI (match_dup 3)
14453                    (match_dup 5)))
14454      (clobber (reg:CC FLAGS_REG))])]
14456   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14457   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14460 (define_expand "tls_dynamic_gnu2_64"
14461   [(set (match_dup 2)
14462         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14463                    UNSPEC_TLSDESC))
14464    (parallel
14465     [(set (match_operand:DI 0 "register_operand" "")
14466           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14467                      UNSPEC_TLSDESC))
14468      (clobber (reg:CC FLAGS_REG))])]
14469   "TARGET_64BIT && TARGET_GNU2_TLS"
14471   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14472   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14475 (define_insn "*tls_dynamic_lea_64"
14476   [(set (match_operand:DI 0 "register_operand" "=r")
14477         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14478                    UNSPEC_TLSDESC))]
14479   "TARGET_64BIT && TARGET_GNU2_TLS"
14480   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14481   [(set_attr "type" "lea")
14482    (set_attr "mode" "DI")
14483    (set_attr "length" "7")
14484    (set_attr "length_address" "4")])
14486 (define_insn "*tls_dynamic_call_64"
14487   [(set (match_operand:DI 0 "register_operand" "=a")
14488         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14489                     (match_operand:DI 2 "register_operand" "0")
14490                     (reg:DI SP_REG)]
14491                    UNSPEC_TLSDESC))
14492    (clobber (reg:CC FLAGS_REG))]
14493   "TARGET_64BIT && TARGET_GNU2_TLS"
14494   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14495   [(set_attr "type" "call")
14496    (set_attr "length" "2")
14497    (set_attr "length_address" "0")])
14499 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14500   [(set (match_operand:DI 0 "register_operand" "=&a")
14501         (plus:DI
14502          (plus:DI (match_operand:DI 2 "tp_or_register_operand" "ir")
14503                   (unspec:DI [(match_operand:DI 3 "tls_modbase_operand" "")
14504                               (match_operand:DI 4 "" "")
14505                               (reg:DI SP_REG)]
14506                               UNSPEC_TLSDESC))
14507          (const:DI (unspec:DI
14508                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14509                     UNSPEC_DTPOFF))))
14510    (clobber (reg:CC FLAGS_REG))]
14511   "TARGET_64BIT && TARGET_GNU2_TLS"
14512   "#"
14513   ""
14514   [(parallel
14515     [(set (match_dup 0)
14516           (plus:DI (match_dup 2)
14517                    (match_dup 4)))
14518      (clobber (reg:CC FLAGS_REG))])]
14520   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14521   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14526 ;; These patterns match the binary 387 instructions for addM3, subM3,
14527 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14528 ;; SFmode.  The first is the normal insn, the second the same insn but
14529 ;; with one operand a conversion, and the third the same insn but with
14530 ;; the other operand a conversion.  The conversion may be SFmode or
14531 ;; SImode if the target mode DFmode, but only SImode if the target mode
14532 ;; is SFmode.
14534 ;; Gcc is slightly more smart about handling normal two address instructions
14535 ;; so use special patterns for add and mull.
14537 (define_insn "*fop_sf_comm_mixed"
14538   [(set (match_operand:SF 0 "register_operand" "=f,x")
14539         (match_operator:SF 3 "binary_fp_operator"
14540                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14541                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14542   "TARGET_MIX_SSE_I387
14543    && COMMUTATIVE_ARITH_P (operands[3])
14544    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14545   "* return output_387_binary_op (insn, operands);"
14546   [(set (attr "type") 
14547         (if_then_else (eq_attr "alternative" "1")
14548            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14549               (const_string "ssemul")
14550               (const_string "sseadd"))
14551            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14552               (const_string "fmul")
14553               (const_string "fop"))))
14554    (set_attr "mode" "SF")])
14556 (define_insn "*fop_sf_comm_sse"
14557   [(set (match_operand:SF 0 "register_operand" "=x")
14558         (match_operator:SF 3 "binary_fp_operator"
14559                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14560                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14561   "TARGET_SSE_MATH
14562    && COMMUTATIVE_ARITH_P (operands[3])
14563    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14564   "* return output_387_binary_op (insn, operands);"
14565   [(set (attr "type") 
14566         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14567            (const_string "ssemul")
14568            (const_string "sseadd")))
14569    (set_attr "mode" "SF")])
14571 (define_insn "*fop_sf_comm_i387"
14572   [(set (match_operand:SF 0 "register_operand" "=f")
14573         (match_operator:SF 3 "binary_fp_operator"
14574                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14575                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14576   "TARGET_80387
14577    && COMMUTATIVE_ARITH_P (operands[3])
14578    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14579   "* return output_387_binary_op (insn, operands);"
14580   [(set (attr "type") 
14581         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14582            (const_string "fmul")
14583            (const_string "fop")))
14584    (set_attr "mode" "SF")])
14586 (define_insn "*fop_sf_1_mixed"
14587   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14588         (match_operator:SF 3 "binary_fp_operator"
14589                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14590                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
14591   "TARGET_MIX_SSE_I387
14592    && !COMMUTATIVE_ARITH_P (operands[3])
14593    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14594   "* return output_387_binary_op (insn, operands);"
14595   [(set (attr "type") 
14596         (cond [(and (eq_attr "alternative" "2")
14597                     (match_operand:SF 3 "mult_operator" ""))
14598                  (const_string "ssemul")
14599                (and (eq_attr "alternative" "2")
14600                     (match_operand:SF 3 "div_operator" ""))
14601                  (const_string "ssediv")
14602                (eq_attr "alternative" "2")
14603                  (const_string "sseadd")
14604                (match_operand:SF 3 "mult_operator" "") 
14605                  (const_string "fmul")
14606                (match_operand:SF 3 "div_operator" "") 
14607                  (const_string "fdiv")
14608               ]
14609               (const_string "fop")))
14610    (set_attr "mode" "SF")])
14612 (define_insn "*fop_sf_1_sse"
14613   [(set (match_operand:SF 0 "register_operand" "=x")
14614         (match_operator:SF 3 "binary_fp_operator"
14615                         [(match_operand:SF 1 "register_operand" "0")
14616                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14617   "TARGET_SSE_MATH
14618    && !COMMUTATIVE_ARITH_P (operands[3])"
14619   "* return output_387_binary_op (insn, operands);"
14620   [(set (attr "type") 
14621         (cond [(match_operand:SF 3 "mult_operator" "")
14622                  (const_string "ssemul")
14623                (match_operand:SF 3 "div_operator" "")
14624                  (const_string "ssediv")
14625               ]
14626               (const_string "sseadd")))
14627    (set_attr "mode" "SF")])
14629 ;; This pattern is not fully shadowed by the pattern above.
14630 (define_insn "*fop_sf_1_i387"
14631   [(set (match_operand:SF 0 "register_operand" "=f,f")
14632         (match_operator:SF 3 "binary_fp_operator"
14633                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14634                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14635   "TARGET_80387 && !TARGET_SSE_MATH
14636    && !COMMUTATIVE_ARITH_P (operands[3])
14637    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14638   "* return output_387_binary_op (insn, operands);"
14639   [(set (attr "type") 
14640         (cond [(match_operand:SF 3 "mult_operator" "") 
14641                  (const_string "fmul")
14642                (match_operand:SF 3 "div_operator" "") 
14643                  (const_string "fdiv")
14644               ]
14645               (const_string "fop")))
14646    (set_attr "mode" "SF")])
14648 ;; ??? Add SSE splitters for these!
14649 (define_insn "*fop_sf_2<mode>_i387"
14650   [(set (match_operand:SF 0 "register_operand" "=f,f")
14651         (match_operator:SF 3 "binary_fp_operator"
14652           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14653            (match_operand:SF 2 "register_operand" "0,0")]))]
14654   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14655   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14656   [(set (attr "type") 
14657         (cond [(match_operand:SF 3 "mult_operator" "") 
14658                  (const_string "fmul")
14659                (match_operand:SF 3 "div_operator" "") 
14660                  (const_string "fdiv")
14661               ]
14662               (const_string "fop")))
14663    (set_attr "fp_int_src" "true")
14664    (set_attr "mode" "<MODE>")])
14666 (define_insn "*fop_sf_3<mode>_i387"
14667   [(set (match_operand:SF 0 "register_operand" "=f,f")
14668         (match_operator:SF 3 "binary_fp_operator"
14669           [(match_operand:SF 1 "register_operand" "0,0")
14670            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14671   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14672   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14673   [(set (attr "type") 
14674         (cond [(match_operand:SF 3 "mult_operator" "") 
14675                  (const_string "fmul")
14676                (match_operand:SF 3 "div_operator" "") 
14677                  (const_string "fdiv")
14678               ]
14679               (const_string "fop")))
14680    (set_attr "fp_int_src" "true")
14681    (set_attr "mode" "<MODE>")])
14683 (define_insn "*fop_df_comm_mixed"
14684   [(set (match_operand:DF 0 "register_operand" "=f,Y")
14685         (match_operator:DF 3 "binary_fp_operator"
14686                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14687                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
14688   "TARGET_SSE2 && TARGET_MIX_SSE_I387
14689    && COMMUTATIVE_ARITH_P (operands[3])
14690    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14691   "* return output_387_binary_op (insn, operands);"
14692   [(set (attr "type") 
14693         (if_then_else (eq_attr "alternative" "1")
14694            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14695               (const_string "ssemul")
14696               (const_string "sseadd"))
14697            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14698               (const_string "fmul")
14699               (const_string "fop"))))
14700    (set_attr "mode" "DF")])
14702 (define_insn "*fop_df_comm_sse"
14703   [(set (match_operand:DF 0 "register_operand" "=Y")
14704         (match_operator:DF 3 "binary_fp_operator"
14705                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14706                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14707   "TARGET_SSE2 && TARGET_SSE_MATH
14708    && COMMUTATIVE_ARITH_P (operands[3])
14709    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14710   "* return output_387_binary_op (insn, operands);"
14711   [(set (attr "type") 
14712         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14713            (const_string "ssemul")
14714            (const_string "sseadd")))
14715    (set_attr "mode" "DF")])
14717 (define_insn "*fop_df_comm_i387"
14718   [(set (match_operand:DF 0 "register_operand" "=f")
14719         (match_operator:DF 3 "binary_fp_operator"
14720                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14721                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14722   "TARGET_80387
14723    && COMMUTATIVE_ARITH_P (operands[3])
14724    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14725   "* return output_387_binary_op (insn, operands);"
14726   [(set (attr "type") 
14727         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14728            (const_string "fmul")
14729            (const_string "fop")))
14730    (set_attr "mode" "DF")])
14732 (define_insn "*fop_df_1_mixed"
14733   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
14734         (match_operator:DF 3 "binary_fp_operator"
14735                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14736                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
14737   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14738    && !COMMUTATIVE_ARITH_P (operands[3])
14739    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14740   "* return output_387_binary_op (insn, operands);"
14741   [(set (attr "type") 
14742         (cond [(and (eq_attr "alternative" "2")
14743                     (match_operand:SF 3 "mult_operator" ""))
14744                  (const_string "ssemul")
14745                (and (eq_attr "alternative" "2")
14746                     (match_operand:SF 3 "div_operator" ""))
14747                  (const_string "ssediv")
14748                (eq_attr "alternative" "2")
14749                  (const_string "sseadd")
14750                (match_operand:DF 3 "mult_operator" "") 
14751                  (const_string "fmul")
14752                (match_operand:DF 3 "div_operator" "") 
14753                  (const_string "fdiv")
14754               ]
14755               (const_string "fop")))
14756    (set_attr "mode" "DF")])
14758 (define_insn "*fop_df_1_sse"
14759   [(set (match_operand:DF 0 "register_operand" "=Y")
14760         (match_operator:DF 3 "binary_fp_operator"
14761                         [(match_operand:DF 1 "register_operand" "0")
14762                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14763   "TARGET_SSE2 && TARGET_SSE_MATH
14764    && !COMMUTATIVE_ARITH_P (operands[3])"
14765   "* return output_387_binary_op (insn, operands);"
14766   [(set_attr "mode" "DF")
14767    (set (attr "type") 
14768         (cond [(match_operand:SF 3 "mult_operator" "")
14769                  (const_string "ssemul")
14770                (match_operand:SF 3 "div_operator" "")
14771                  (const_string "ssediv")
14772               ]
14773               (const_string "sseadd")))])
14775 ;; This pattern is not fully shadowed by the pattern above.
14776 (define_insn "*fop_df_1_i387"
14777   [(set (match_operand:DF 0 "register_operand" "=f,f")
14778         (match_operator:DF 3 "binary_fp_operator"
14779                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14780                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14781   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14782    && !COMMUTATIVE_ARITH_P (operands[3])
14783    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14784   "* return output_387_binary_op (insn, operands);"
14785   [(set (attr "type") 
14786         (cond [(match_operand:DF 3 "mult_operator" "") 
14787                  (const_string "fmul")
14788                (match_operand:DF 3 "div_operator" "")
14789                  (const_string "fdiv")
14790               ]
14791               (const_string "fop")))
14792    (set_attr "mode" "DF")])
14794 ;; ??? Add SSE splitters for these!
14795 (define_insn "*fop_df_2<mode>_i387"
14796   [(set (match_operand:DF 0 "register_operand" "=f,f")
14797         (match_operator:DF 3 "binary_fp_operator"
14798            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14799             (match_operand:DF 2 "register_operand" "0,0")]))]
14800   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14801    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14802   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14803   [(set (attr "type") 
14804         (cond [(match_operand:DF 3 "mult_operator" "") 
14805                  (const_string "fmul")
14806                (match_operand:DF 3 "div_operator" "") 
14807                  (const_string "fdiv")
14808               ]
14809               (const_string "fop")))
14810    (set_attr "fp_int_src" "true")
14811    (set_attr "mode" "<MODE>")])
14813 (define_insn "*fop_df_3<mode>_i387"
14814   [(set (match_operand:DF 0 "register_operand" "=f,f")
14815         (match_operator:DF 3 "binary_fp_operator"
14816            [(match_operand:DF 1 "register_operand" "0,0")
14817             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14818   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14819    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14820   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14821   [(set (attr "type") 
14822         (cond [(match_operand:DF 3 "mult_operator" "") 
14823                  (const_string "fmul")
14824                (match_operand:DF 3 "div_operator" "") 
14825                  (const_string "fdiv")
14826               ]
14827               (const_string "fop")))
14828    (set_attr "fp_int_src" "true")
14829    (set_attr "mode" "<MODE>")])
14831 (define_insn "*fop_df_4_i387"
14832   [(set (match_operand:DF 0 "register_operand" "=f,f")
14833         (match_operator:DF 3 "binary_fp_operator"
14834            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14835             (match_operand:DF 2 "register_operand" "0,f")]))]
14836   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14837    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14838   "* return output_387_binary_op (insn, operands);"
14839   [(set (attr "type") 
14840         (cond [(match_operand:DF 3 "mult_operator" "") 
14841                  (const_string "fmul")
14842                (match_operand:DF 3 "div_operator" "") 
14843                  (const_string "fdiv")
14844               ]
14845               (const_string "fop")))
14846    (set_attr "mode" "SF")])
14848 (define_insn "*fop_df_5_i387"
14849   [(set (match_operand:DF 0 "register_operand" "=f,f")
14850         (match_operator:DF 3 "binary_fp_operator"
14851           [(match_operand:DF 1 "register_operand" "0,f")
14852            (float_extend:DF
14853             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14854   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14855   "* return output_387_binary_op (insn, operands);"
14856   [(set (attr "type") 
14857         (cond [(match_operand:DF 3 "mult_operator" "") 
14858                  (const_string "fmul")
14859                (match_operand:DF 3 "div_operator" "") 
14860                  (const_string "fdiv")
14861               ]
14862               (const_string "fop")))
14863    (set_attr "mode" "SF")])
14865 (define_insn "*fop_df_6_i387"
14866   [(set (match_operand:DF 0 "register_operand" "=f,f")
14867         (match_operator:DF 3 "binary_fp_operator"
14868           [(float_extend:DF
14869             (match_operand:SF 1 "register_operand" "0,f"))
14870            (float_extend:DF
14871             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14872   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14873   "* return output_387_binary_op (insn, operands);"
14874   [(set (attr "type") 
14875         (cond [(match_operand:DF 3 "mult_operator" "") 
14876                  (const_string "fmul")
14877                (match_operand:DF 3 "div_operator" "") 
14878                  (const_string "fdiv")
14879               ]
14880               (const_string "fop")))
14881    (set_attr "mode" "SF")])
14883 (define_insn "*fop_xf_comm_i387"
14884   [(set (match_operand:XF 0 "register_operand" "=f")
14885         (match_operator:XF 3 "binary_fp_operator"
14886                         [(match_operand:XF 1 "register_operand" "%0")
14887                          (match_operand:XF 2 "register_operand" "f")]))]
14888   "TARGET_80387
14889    && COMMUTATIVE_ARITH_P (operands[3])"
14890   "* return output_387_binary_op (insn, operands);"
14891   [(set (attr "type") 
14892         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14893            (const_string "fmul")
14894            (const_string "fop")))
14895    (set_attr "mode" "XF")])
14897 (define_insn "*fop_xf_1_i387"
14898   [(set (match_operand:XF 0 "register_operand" "=f,f")
14899         (match_operator:XF 3 "binary_fp_operator"
14900                         [(match_operand:XF 1 "register_operand" "0,f")
14901                          (match_operand:XF 2 "register_operand" "f,0")]))]
14902   "TARGET_80387
14903    && !COMMUTATIVE_ARITH_P (operands[3])"
14904   "* return output_387_binary_op (insn, operands);"
14905   [(set (attr "type") 
14906         (cond [(match_operand:XF 3 "mult_operator" "") 
14907                  (const_string "fmul")
14908                (match_operand:XF 3 "div_operator" "") 
14909                  (const_string "fdiv")
14910               ]
14911               (const_string "fop")))
14912    (set_attr "mode" "XF")])
14914 (define_insn "*fop_xf_2<mode>_i387"
14915   [(set (match_operand:XF 0 "register_operand" "=f,f")
14916         (match_operator:XF 3 "binary_fp_operator"
14917            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14918             (match_operand:XF 2 "register_operand" "0,0")]))]
14919   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14920   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14921   [(set (attr "type") 
14922         (cond [(match_operand:XF 3 "mult_operator" "") 
14923                  (const_string "fmul")
14924                (match_operand:XF 3 "div_operator" "") 
14925                  (const_string "fdiv")
14926               ]
14927               (const_string "fop")))
14928    (set_attr "fp_int_src" "true")
14929    (set_attr "mode" "<MODE>")])
14931 (define_insn "*fop_xf_3<mode>_i387"
14932   [(set (match_operand:XF 0 "register_operand" "=f,f")
14933         (match_operator:XF 3 "binary_fp_operator"
14934           [(match_operand:XF 1 "register_operand" "0,0")
14935            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14936   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14937   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14938   [(set (attr "type") 
14939         (cond [(match_operand:XF 3 "mult_operator" "") 
14940                  (const_string "fmul")
14941                (match_operand:XF 3 "div_operator" "") 
14942                  (const_string "fdiv")
14943               ]
14944               (const_string "fop")))
14945    (set_attr "fp_int_src" "true")
14946    (set_attr "mode" "<MODE>")])
14948 (define_insn "*fop_xf_4_i387"
14949   [(set (match_operand:XF 0 "register_operand" "=f,f")
14950         (match_operator:XF 3 "binary_fp_operator"
14951            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14952             (match_operand:XF 2 "register_operand" "0,f")]))]
14953   "TARGET_80387"
14954   "* return output_387_binary_op (insn, operands);"
14955   [(set (attr "type") 
14956         (cond [(match_operand:XF 3 "mult_operator" "") 
14957                  (const_string "fmul")
14958                (match_operand:XF 3 "div_operator" "") 
14959                  (const_string "fdiv")
14960               ]
14961               (const_string "fop")))
14962    (set_attr "mode" "SF")])
14964 (define_insn "*fop_xf_5_i387"
14965   [(set (match_operand:XF 0 "register_operand" "=f,f")
14966         (match_operator:XF 3 "binary_fp_operator"
14967           [(match_operand:XF 1 "register_operand" "0,f")
14968            (float_extend:XF
14969             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14970   "TARGET_80387"
14971   "* return output_387_binary_op (insn, operands);"
14972   [(set (attr "type") 
14973         (cond [(match_operand:XF 3 "mult_operator" "") 
14974                  (const_string "fmul")
14975                (match_operand:XF 3 "div_operator" "") 
14976                  (const_string "fdiv")
14977               ]
14978               (const_string "fop")))
14979    (set_attr "mode" "SF")])
14981 (define_insn "*fop_xf_6_i387"
14982   [(set (match_operand:XF 0 "register_operand" "=f,f")
14983         (match_operator:XF 3 "binary_fp_operator"
14984           [(float_extend:XF
14985             (match_operand 1 "register_operand" "0,f"))
14986            (float_extend:XF
14987             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14988   "TARGET_80387"
14989   "* return output_387_binary_op (insn, operands);"
14990   [(set (attr "type") 
14991         (cond [(match_operand:XF 3 "mult_operator" "") 
14992                  (const_string "fmul")
14993                (match_operand:XF 3 "div_operator" "") 
14994                  (const_string "fdiv")
14995               ]
14996               (const_string "fop")))
14997    (set_attr "mode" "SF")])
14999 (define_split
15000   [(set (match_operand 0 "register_operand" "")
15001         (match_operator 3 "binary_fp_operator"
15002            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15003             (match_operand 2 "register_operand" "")]))]
15004   "TARGET_80387 && reload_completed
15005    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15006   [(const_int 0)]
15008   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15009   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15010   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15011                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15012                                           GET_MODE (operands[3]),
15013                                           operands[4],
15014                                           operands[2])));
15015   ix86_free_from_memory (GET_MODE (operands[1]));
15016   DONE;
15019 (define_split
15020   [(set (match_operand 0 "register_operand" "")
15021         (match_operator 3 "binary_fp_operator"
15022            [(match_operand 1 "register_operand" "")
15023             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15024   "TARGET_80387 && reload_completed
15025    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15026   [(const_int 0)]
15028   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15029   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15030   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15031                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15032                                           GET_MODE (operands[3]),
15033                                           operands[1],
15034                                           operands[4])));
15035   ix86_free_from_memory (GET_MODE (operands[2]));
15036   DONE;
15039 ;; FPU special functions.
15041 (define_expand "sqrtsf2"
15042   [(set (match_operand:SF 0 "register_operand" "")
15043         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15044   "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15046   if (!TARGET_SSE_MATH)
15047     operands[1] = force_reg (SFmode, operands[1]);
15050 (define_insn "*sqrtsf2_mixed"
15051   [(set (match_operand:SF 0 "register_operand" "=f,x")
15052         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15053   "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15054   "@
15055    fsqrt
15056    sqrtss\t{%1, %0|%0, %1}"
15057   [(set_attr "type" "fpspc,sse")
15058    (set_attr "mode" "SF,SF")
15059    (set_attr "athlon_decode" "direct,*")])
15061 (define_insn "*sqrtsf2_sse"
15062   [(set (match_operand:SF 0 "register_operand" "=x")
15063         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15064   "TARGET_SSE_MATH"
15065   "sqrtss\t{%1, %0|%0, %1}"
15066   [(set_attr "type" "sse")
15067    (set_attr "mode" "SF")
15068    (set_attr "athlon_decode" "*")])
15070 (define_insn "*sqrtsf2_i387"
15071   [(set (match_operand:SF 0 "register_operand" "=f")
15072         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15073   "TARGET_USE_FANCY_MATH_387"
15074   "fsqrt"
15075   [(set_attr "type" "fpspc")
15076    (set_attr "mode" "SF")
15077    (set_attr "athlon_decode" "direct")])
15079 (define_expand "sqrtdf2"
15080   [(set (match_operand:DF 0 "register_operand" "")
15081         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15082   "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15084   if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15085     operands[1] = force_reg (DFmode, operands[1]);
15088 (define_insn "*sqrtdf2_mixed"
15089   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15090         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15091   "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15092   "@
15093    fsqrt
15094    sqrtsd\t{%1, %0|%0, %1}"
15095   [(set_attr "type" "fpspc,sse")
15096    (set_attr "mode" "DF,DF")
15097    (set_attr "athlon_decode" "direct,*")])
15099 (define_insn "*sqrtdf2_sse"
15100   [(set (match_operand:DF 0 "register_operand" "=Y")
15101         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15102   "TARGET_SSE2 && TARGET_SSE_MATH"
15103   "sqrtsd\t{%1, %0|%0, %1}"
15104   [(set_attr "type" "sse")
15105    (set_attr "mode" "DF")
15106    (set_attr "athlon_decode" "*")])
15108 (define_insn "*sqrtdf2_i387"
15109   [(set (match_operand:DF 0 "register_operand" "=f")
15110         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15111   "TARGET_USE_FANCY_MATH_387"
15112   "fsqrt"
15113   [(set_attr "type" "fpspc")
15114    (set_attr "mode" "DF")
15115    (set_attr "athlon_decode" "direct")])
15117 (define_insn "*sqrtextendsfdf2_i387"
15118   [(set (match_operand:DF 0 "register_operand" "=f")
15119         (sqrt:DF (float_extend:DF
15120                   (match_operand:SF 1 "register_operand" "0"))))]
15121   "TARGET_USE_FANCY_MATH_387
15122    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15123   "fsqrt"
15124   [(set_attr "type" "fpspc")
15125    (set_attr "mode" "DF")
15126    (set_attr "athlon_decode" "direct")])
15128 (define_insn "sqrtxf2"
15129   [(set (match_operand:XF 0 "register_operand" "=f")
15130         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15131   "TARGET_USE_FANCY_MATH_387 
15132    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15133   "fsqrt"
15134   [(set_attr "type" "fpspc")
15135    (set_attr "mode" "XF")
15136    (set_attr "athlon_decode" "direct")])
15138 (define_insn "*sqrtextendsfxf2_i387"
15139   [(set (match_operand:XF 0 "register_operand" "=f")
15140         (sqrt:XF (float_extend:XF
15141                   (match_operand:SF 1 "register_operand" "0"))))]
15142   "TARGET_USE_FANCY_MATH_387"
15143   "fsqrt"
15144   [(set_attr "type" "fpspc")
15145    (set_attr "mode" "XF")
15146    (set_attr "athlon_decode" "direct")])
15148 (define_insn "*sqrtextenddfxf2_i387"
15149   [(set (match_operand:XF 0 "register_operand" "=f")
15150         (sqrt:XF (float_extend:XF
15151                   (match_operand:DF 1 "register_operand" "0"))))]
15152   "TARGET_USE_FANCY_MATH_387"
15153   "fsqrt"
15154   [(set_attr "type" "fpspc")
15155    (set_attr "mode" "XF")
15156    (set_attr "athlon_decode" "direct")])
15158 (define_insn "fpremxf4"
15159   [(set (match_operand:XF 0 "register_operand" "=f")
15160         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15161                     (match_operand:XF 3 "register_operand" "1")]
15162                    UNSPEC_FPREM_F))
15163    (set (match_operand:XF 1 "register_operand" "=u")
15164         (unspec:XF [(match_dup 2) (match_dup 3)]
15165                    UNSPEC_FPREM_U))
15166    (set (reg:CCFP FPSR_REG)
15167         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15168   "TARGET_USE_FANCY_MATH_387
15169    && flag_unsafe_math_optimizations"
15170   "fprem"
15171   [(set_attr "type" "fpspc")
15172    (set_attr "mode" "XF")])
15174 (define_expand "fmodsf3"
15175   [(use (match_operand:SF 0 "register_operand" ""))
15176    (use (match_operand:SF 1 "register_operand" ""))
15177    (use (match_operand:SF 2 "register_operand" ""))]
15178   "TARGET_USE_FANCY_MATH_387
15179    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15180    && flag_unsafe_math_optimizations"
15182   rtx label = gen_label_rtx ();
15184   rtx op1 = gen_reg_rtx (XFmode);
15185   rtx op2 = gen_reg_rtx (XFmode);
15187   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15188   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15190   emit_label (label);
15192   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15193   ix86_emit_fp_unordered_jump (label);
15195   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15196   DONE;
15199 (define_expand "fmoddf3"
15200   [(use (match_operand:DF 0 "register_operand" ""))
15201    (use (match_operand:DF 1 "register_operand" ""))
15202    (use (match_operand:DF 2 "register_operand" ""))]
15203   "TARGET_USE_FANCY_MATH_387
15204    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15205    && flag_unsafe_math_optimizations"
15207   rtx label = gen_label_rtx ();
15209   rtx op1 = gen_reg_rtx (XFmode);
15210   rtx op2 = gen_reg_rtx (XFmode);
15212   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15213   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15215   emit_label (label);
15217   emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15218   ix86_emit_fp_unordered_jump (label);
15220   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15221   DONE;
15224 (define_expand "fmodxf3"
15225   [(use (match_operand:XF 0 "register_operand" ""))
15226    (use (match_operand:XF 1 "register_operand" ""))
15227    (use (match_operand:XF 2 "register_operand" ""))]
15228   "TARGET_USE_FANCY_MATH_387
15229    && flag_unsafe_math_optimizations"
15231   rtx label = gen_label_rtx ();
15233   emit_label (label);
15235   emit_insn (gen_fpremxf4 (operands[1], operands[2],
15236                            operands[1], operands[2]));
15237   ix86_emit_fp_unordered_jump (label);
15239   emit_move_insn (operands[0], operands[1]);
15240   DONE;
15243 (define_insn "fprem1xf4"
15244   [(set (match_operand:XF 0 "register_operand" "=f")
15245         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15246                     (match_operand:XF 3 "register_operand" "1")]
15247                    UNSPEC_FPREM1_F))
15248    (set (match_operand:XF 1 "register_operand" "=u")
15249         (unspec:XF [(match_dup 2) (match_dup 3)]
15250                    UNSPEC_FPREM1_U))
15251    (set (reg:CCFP FPSR_REG)
15252         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15253   "TARGET_USE_FANCY_MATH_387
15254    && flag_unsafe_math_optimizations"
15255   "fprem1"
15256   [(set_attr "type" "fpspc")
15257    (set_attr "mode" "XF")])
15259 (define_expand "dremsf3"
15260   [(use (match_operand:SF 0 "register_operand" ""))
15261    (use (match_operand:SF 1 "register_operand" ""))
15262    (use (match_operand:SF 2 "register_operand" ""))]
15263   "TARGET_USE_FANCY_MATH_387
15264    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15265    && flag_unsafe_math_optimizations"
15267   rtx label = gen_label_rtx ();
15269   rtx op1 = gen_reg_rtx (XFmode);
15270   rtx op2 = gen_reg_rtx (XFmode);
15272   emit_insn(gen_extendsfxf2 (op1, operands[1]));
15273   emit_insn(gen_extendsfxf2 (op2, operands[2]));
15275   emit_label (label);
15277   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15278   ix86_emit_fp_unordered_jump (label);
15280   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15281   DONE;
15284 (define_expand "dremdf3"
15285   [(use (match_operand:DF 0 "register_operand" ""))
15286    (use (match_operand:DF 1 "register_operand" ""))
15287    (use (match_operand:DF 2 "register_operand" ""))]
15288   "TARGET_USE_FANCY_MATH_387
15289    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15290    && flag_unsafe_math_optimizations"
15292   rtx label = gen_label_rtx ();
15294   rtx op1 = gen_reg_rtx (XFmode);
15295   rtx op2 = gen_reg_rtx (XFmode);
15297   emit_insn (gen_extenddfxf2 (op1, operands[1]));
15298   emit_insn (gen_extenddfxf2 (op2, operands[2]));
15300   emit_label (label);
15302   emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15303   ix86_emit_fp_unordered_jump (label);
15305   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15306   DONE;
15309 (define_expand "dremxf3"
15310   [(use (match_operand:XF 0 "register_operand" ""))
15311    (use (match_operand:XF 1 "register_operand" ""))
15312    (use (match_operand:XF 2 "register_operand" ""))]
15313   "TARGET_USE_FANCY_MATH_387
15314    && flag_unsafe_math_optimizations"
15316   rtx label = gen_label_rtx ();
15318   emit_label (label);
15320   emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15321                             operands[1], operands[2]));
15322   ix86_emit_fp_unordered_jump (label);
15324   emit_move_insn (operands[0], operands[1]);
15325   DONE;
15328 (define_insn "*sindf2"
15329   [(set (match_operand:DF 0 "register_operand" "=f")
15330         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15331   "TARGET_USE_FANCY_MATH_387
15332    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15333    && flag_unsafe_math_optimizations"
15334   "fsin"
15335   [(set_attr "type" "fpspc")
15336    (set_attr "mode" "DF")])
15338 (define_insn "*sinsf2"
15339   [(set (match_operand:SF 0 "register_operand" "=f")
15340         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15341   "TARGET_USE_FANCY_MATH_387
15342    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15343    && flag_unsafe_math_optimizations"
15344   "fsin"
15345   [(set_attr "type" "fpspc")
15346    (set_attr "mode" "SF")])
15348 (define_insn "*sinextendsfdf2"
15349   [(set (match_operand:DF 0 "register_operand" "=f")
15350         (unspec:DF [(float_extend:DF
15351                      (match_operand:SF 1 "register_operand" "0"))]
15352                    UNSPEC_SIN))]
15353   "TARGET_USE_FANCY_MATH_387
15354    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15355    && flag_unsafe_math_optimizations"
15356   "fsin"
15357   [(set_attr "type" "fpspc")
15358    (set_attr "mode" "DF")])
15360 (define_insn "*sinxf2"
15361   [(set (match_operand:XF 0 "register_operand" "=f")
15362         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15363   "TARGET_USE_FANCY_MATH_387
15364    && flag_unsafe_math_optimizations"
15365   "fsin"
15366   [(set_attr "type" "fpspc")
15367    (set_attr "mode" "XF")])
15369 (define_insn "*cosdf2"
15370   [(set (match_operand:DF 0 "register_operand" "=f")
15371         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15372   "TARGET_USE_FANCY_MATH_387
15373    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15374    && flag_unsafe_math_optimizations"
15375   "fcos"
15376   [(set_attr "type" "fpspc")
15377    (set_attr "mode" "DF")])
15379 (define_insn "*cossf2"
15380   [(set (match_operand:SF 0 "register_operand" "=f")
15381         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15382   "TARGET_USE_FANCY_MATH_387
15383    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15384    && flag_unsafe_math_optimizations"
15385   "fcos"
15386   [(set_attr "type" "fpspc")
15387    (set_attr "mode" "SF")])
15389 (define_insn "*cosextendsfdf2"
15390   [(set (match_operand:DF 0 "register_operand" "=f")
15391         (unspec:DF [(float_extend:DF
15392                      (match_operand:SF 1 "register_operand" "0"))]
15393                    UNSPEC_COS))]
15394   "TARGET_USE_FANCY_MATH_387
15395    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15396    && flag_unsafe_math_optimizations"
15397   "fcos"
15398   [(set_attr "type" "fpspc")
15399    (set_attr "mode" "DF")])
15401 (define_insn "*cosxf2"
15402   [(set (match_operand:XF 0 "register_operand" "=f")
15403         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15404   "TARGET_USE_FANCY_MATH_387
15405    && flag_unsafe_math_optimizations"
15406   "fcos"
15407   [(set_attr "type" "fpspc")
15408    (set_attr "mode" "XF")])
15410 ;; With sincos pattern defined, sin and cos builtin function will be
15411 ;; expanded to sincos pattern with one of its outputs left unused. 
15412 ;; Cse pass  will detected, if two sincos patterns can be combined,
15413 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15414 ;; depending on the unused output.
15416 (define_insn "sincosdf3"
15417   [(set (match_operand:DF 0 "register_operand" "=f")
15418         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15419                    UNSPEC_SINCOS_COS))
15420    (set (match_operand:DF 1 "register_operand" "=u")
15421         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15422   "TARGET_USE_FANCY_MATH_387
15423    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15424    && flag_unsafe_math_optimizations"
15425   "fsincos"
15426   [(set_attr "type" "fpspc")
15427    (set_attr "mode" "DF")])
15429 (define_split
15430   [(set (match_operand:DF 0 "register_operand" "")
15431         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15432                    UNSPEC_SINCOS_COS))
15433    (set (match_operand:DF 1 "register_operand" "")
15434         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15435   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15436    && !reload_completed && !reload_in_progress"
15437   [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15438   "")
15440 (define_split
15441   [(set (match_operand:DF 0 "register_operand" "")
15442         (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15443                    UNSPEC_SINCOS_COS))
15444    (set (match_operand:DF 1 "register_operand" "")
15445         (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15446   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15447    && !reload_completed && !reload_in_progress"
15448   [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15449   "")
15451 (define_insn "sincossf3"
15452   [(set (match_operand:SF 0 "register_operand" "=f")
15453         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15454                    UNSPEC_SINCOS_COS))
15455    (set (match_operand:SF 1 "register_operand" "=u")
15456         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15457   "TARGET_USE_FANCY_MATH_387
15458    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15459    && flag_unsafe_math_optimizations"
15460   "fsincos"
15461   [(set_attr "type" "fpspc")
15462    (set_attr "mode" "SF")])
15464 (define_split
15465   [(set (match_operand:SF 0 "register_operand" "")
15466         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15467                    UNSPEC_SINCOS_COS))
15468    (set (match_operand:SF 1 "register_operand" "")
15469         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15470   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15471    && !reload_completed && !reload_in_progress"
15472   [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15473   "")
15475 (define_split
15476   [(set (match_operand:SF 0 "register_operand" "")
15477         (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15478                    UNSPEC_SINCOS_COS))
15479    (set (match_operand:SF 1 "register_operand" "")
15480         (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15481   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15482    && !reload_completed && !reload_in_progress"
15483   [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15484   "")
15486 (define_insn "*sincosextendsfdf3"
15487   [(set (match_operand:DF 0 "register_operand" "=f")
15488         (unspec:DF [(float_extend:DF
15489                      (match_operand:SF 2 "register_operand" "0"))]
15490                    UNSPEC_SINCOS_COS))
15491    (set (match_operand:DF 1 "register_operand" "=u")
15492         (unspec:DF [(float_extend:DF
15493                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15494   "TARGET_USE_FANCY_MATH_387
15495    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15496    && flag_unsafe_math_optimizations"
15497   "fsincos"
15498   [(set_attr "type" "fpspc")
15499    (set_attr "mode" "DF")])
15501 (define_split
15502   [(set (match_operand:DF 0 "register_operand" "")
15503         (unspec:DF [(float_extend:DF
15504                      (match_operand:SF 2 "register_operand" ""))]
15505                    UNSPEC_SINCOS_COS))
15506    (set (match_operand:DF 1 "register_operand" "")
15507         (unspec:DF [(float_extend:DF
15508                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15509   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15510    && !reload_completed && !reload_in_progress"
15511   [(set (match_dup 1) (unspec:DF [(float_extend:DF
15512                                    (match_dup 2))] UNSPEC_SIN))]
15513   "")
15515 (define_split
15516   [(set (match_operand:DF 0 "register_operand" "")
15517         (unspec:DF [(float_extend:DF
15518                      (match_operand:SF 2 "register_operand" ""))]
15519                    UNSPEC_SINCOS_COS))
15520    (set (match_operand:DF 1 "register_operand" "")
15521         (unspec:DF [(float_extend:DF
15522                      (match_dup 2))] UNSPEC_SINCOS_SIN))]
15523   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15524    && !reload_completed && !reload_in_progress"
15525   [(set (match_dup 0) (unspec:DF [(float_extend:DF
15526                                    (match_dup 2))] UNSPEC_COS))]
15527   "")
15529 (define_insn "sincosxf3"
15530   [(set (match_operand:XF 0 "register_operand" "=f")
15531         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15532                    UNSPEC_SINCOS_COS))
15533    (set (match_operand:XF 1 "register_operand" "=u")
15534         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15535   "TARGET_USE_FANCY_MATH_387
15536    && flag_unsafe_math_optimizations"
15537   "fsincos"
15538   [(set_attr "type" "fpspc")
15539    (set_attr "mode" "XF")])
15541 (define_split
15542   [(set (match_operand:XF 0 "register_operand" "")
15543         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15544                    UNSPEC_SINCOS_COS))
15545    (set (match_operand:XF 1 "register_operand" "")
15546         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15547   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15548    && !reload_completed && !reload_in_progress"
15549   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15550   "")
15552 (define_split
15553   [(set (match_operand:XF 0 "register_operand" "")
15554         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15555                    UNSPEC_SINCOS_COS))
15556    (set (match_operand:XF 1 "register_operand" "")
15557         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15558   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15559    && !reload_completed && !reload_in_progress"
15560   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15561   "")
15563 (define_insn "*tandf3_1"
15564   [(set (match_operand:DF 0 "register_operand" "=f")
15565         (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15566                    UNSPEC_TAN_ONE))
15567    (set (match_operand:DF 1 "register_operand" "=u")
15568         (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15569   "TARGET_USE_FANCY_MATH_387
15570    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15571    && flag_unsafe_math_optimizations"
15572   "fptan"
15573   [(set_attr "type" "fpspc")
15574    (set_attr "mode" "DF")])
15576 ;; optimize sequence: fptan
15577 ;;                    fstp    %st(0)
15578 ;;                    fld1
15579 ;; into fptan insn.
15581 (define_peephole2
15582   [(parallel[(set (match_operand:DF 0 "register_operand" "")
15583                   (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15584                              UNSPEC_TAN_ONE))
15585              (set (match_operand:DF 1 "register_operand" "")
15586                   (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15587    (set (match_dup 0)
15588         (match_operand:DF 3 "immediate_operand" ""))]
15589   "standard_80387_constant_p (operands[3]) == 2"
15590   [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15591              (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15592   "")
15594 (define_expand "tandf2"
15595   [(parallel [(set (match_dup 2)
15596                    (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15597                               UNSPEC_TAN_ONE))
15598               (set (match_operand:DF 0 "register_operand" "")
15599                    (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15600   "TARGET_USE_FANCY_MATH_387
15601    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15602    && flag_unsafe_math_optimizations"
15604   operands[2] = gen_reg_rtx (DFmode);
15607 (define_insn "*tansf3_1"
15608   [(set (match_operand:SF 0 "register_operand" "=f")
15609         (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15610                    UNSPEC_TAN_ONE))
15611    (set (match_operand:SF 1 "register_operand" "=u")
15612         (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15613   "TARGET_USE_FANCY_MATH_387
15614    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15615    && flag_unsafe_math_optimizations"
15616   "fptan"
15617   [(set_attr "type" "fpspc")
15618    (set_attr "mode" "SF")])
15620 ;; optimize sequence: fptan
15621 ;;                    fstp    %st(0)
15622 ;;                    fld1
15623 ;; into fptan insn.
15625 (define_peephole2
15626   [(parallel[(set (match_operand:SF 0 "register_operand" "")
15627                   (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15628                              UNSPEC_TAN_ONE))
15629              (set (match_operand:SF 1 "register_operand" "")
15630                   (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15631    (set (match_dup 0)
15632         (match_operand:SF 3 "immediate_operand" ""))]
15633   "standard_80387_constant_p (operands[3]) == 2"
15634   [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15635              (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15636   "")
15638 (define_expand "tansf2"
15639   [(parallel [(set (match_dup 2)
15640                    (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15641                               UNSPEC_TAN_ONE))
15642               (set (match_operand:SF 0 "register_operand" "")
15643                    (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15644   "TARGET_USE_FANCY_MATH_387
15645    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15646    && flag_unsafe_math_optimizations"
15648   operands[2] = gen_reg_rtx (SFmode);
15651 (define_insn "*tanxf3_1"
15652   [(set (match_operand:XF 0 "register_operand" "=f")
15653         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15654                    UNSPEC_TAN_ONE))
15655    (set (match_operand:XF 1 "register_operand" "=u")
15656         (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15657   "TARGET_USE_FANCY_MATH_387
15658    && flag_unsafe_math_optimizations"
15659   "fptan"
15660   [(set_attr "type" "fpspc")
15661    (set_attr "mode" "XF")])
15663 ;; optimize sequence: fptan
15664 ;;                    fstp    %st(0)
15665 ;;                    fld1
15666 ;; into fptan insn.
15668 (define_peephole2
15669   [(parallel[(set (match_operand:XF 0 "register_operand" "")
15670                   (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15671                              UNSPEC_TAN_ONE))
15672              (set (match_operand:XF 1 "register_operand" "")
15673                   (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15674    (set (match_dup 0)
15675         (match_operand:XF 3 "immediate_operand" ""))]
15676   "standard_80387_constant_p (operands[3]) == 2"
15677   [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15678              (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15679   "")
15681 (define_expand "tanxf2"
15682   [(parallel [(set (match_dup 2)
15683                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15684                               UNSPEC_TAN_ONE))
15685               (set (match_operand:XF 0 "register_operand" "")
15686                    (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15687   "TARGET_USE_FANCY_MATH_387
15688    && flag_unsafe_math_optimizations"
15690   operands[2] = gen_reg_rtx (XFmode);
15693 (define_insn "atan2df3_1"
15694   [(set (match_operand:DF 0 "register_operand" "=f")
15695         (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15696                     (match_operand:DF 1 "register_operand" "u")]
15697                    UNSPEC_FPATAN))
15698    (clobber (match_scratch:DF 3 "=1"))]
15699   "TARGET_USE_FANCY_MATH_387
15700    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15701    && flag_unsafe_math_optimizations"
15702   "fpatan"
15703   [(set_attr "type" "fpspc")
15704    (set_attr "mode" "DF")])
15706 (define_expand "atan2df3"
15707   [(use (match_operand:DF 0 "register_operand" ""))
15708    (use (match_operand:DF 2 "register_operand" ""))
15709    (use (match_operand:DF 1 "register_operand" ""))]
15710   "TARGET_USE_FANCY_MATH_387
15711    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15712    && flag_unsafe_math_optimizations"
15714   rtx copy = gen_reg_rtx (DFmode);
15715   emit_move_insn (copy, operands[1]);
15716   emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15717   DONE;
15720 (define_expand "atandf2"
15721   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15722                    (unspec:DF [(match_dup 2)
15723                                (match_operand:DF 1 "register_operand" "")]
15724                     UNSPEC_FPATAN))
15725               (clobber (match_scratch:DF 3 ""))])]
15726   "TARGET_USE_FANCY_MATH_387
15727    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15728    && flag_unsafe_math_optimizations"
15730   operands[2] = gen_reg_rtx (DFmode);
15731   emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
15734 (define_insn "atan2sf3_1"
15735   [(set (match_operand:SF 0 "register_operand" "=f")
15736         (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15737                     (match_operand:SF 1 "register_operand" "u")]
15738                    UNSPEC_FPATAN))
15739    (clobber (match_scratch:SF 3 "=1"))]
15740   "TARGET_USE_FANCY_MATH_387
15741    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15742    && flag_unsafe_math_optimizations"
15743   "fpatan"
15744   [(set_attr "type" "fpspc")
15745    (set_attr "mode" "SF")])
15747 (define_expand "atan2sf3"
15748   [(use (match_operand:SF 0 "register_operand" ""))
15749    (use (match_operand:SF 2 "register_operand" ""))
15750    (use (match_operand:SF 1 "register_operand" ""))]
15751   "TARGET_USE_FANCY_MATH_387
15752    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15753    && flag_unsafe_math_optimizations"
15755   rtx copy = gen_reg_rtx (SFmode);
15756   emit_move_insn (copy, operands[1]);
15757   emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15758   DONE;
15761 (define_expand "atansf2"
15762   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15763                    (unspec:SF [(match_dup 2)
15764                                (match_operand:SF 1 "register_operand" "")]
15765                     UNSPEC_FPATAN))
15766               (clobber (match_scratch:SF 3 ""))])]
15767   "TARGET_USE_FANCY_MATH_387
15768    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15769    && flag_unsafe_math_optimizations"
15771   operands[2] = gen_reg_rtx (SFmode);
15772   emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
15775 (define_insn "atan2xf3_1"
15776   [(set (match_operand:XF 0 "register_operand" "=f")
15777         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15778                     (match_operand:XF 1 "register_operand" "u")]
15779                    UNSPEC_FPATAN))
15780    (clobber (match_scratch:XF 3 "=1"))]
15781   "TARGET_USE_FANCY_MATH_387
15782    && flag_unsafe_math_optimizations"
15783   "fpatan"
15784   [(set_attr "type" "fpspc")
15785    (set_attr "mode" "XF")])
15787 (define_expand "atan2xf3"
15788   [(use (match_operand:XF 0 "register_operand" ""))
15789    (use (match_operand:XF 2 "register_operand" ""))
15790    (use (match_operand:XF 1 "register_operand" ""))]
15791   "TARGET_USE_FANCY_MATH_387
15792    && flag_unsafe_math_optimizations"
15794   rtx copy = gen_reg_rtx (XFmode);
15795   emit_move_insn (copy, operands[1]);
15796   emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15797   DONE;
15800 (define_expand "atanxf2"
15801   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15802                    (unspec:XF [(match_dup 2)
15803                                (match_operand:XF 1 "register_operand" "")]
15804                     UNSPEC_FPATAN))
15805               (clobber (match_scratch:XF 3 ""))])]
15806   "TARGET_USE_FANCY_MATH_387
15807    && flag_unsafe_math_optimizations"
15809   operands[2] = gen_reg_rtx (XFmode);
15810   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15813 (define_expand "asindf2"
15814   [(set (match_dup 2)
15815         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15816    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15817    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15818    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15819    (parallel [(set (match_dup 7)
15820                    (unspec:XF [(match_dup 6) (match_dup 2)]
15821                               UNSPEC_FPATAN))
15822               (clobber (match_scratch:XF 8 ""))])
15823    (set (match_operand:DF 0 "register_operand" "")
15824         (float_truncate:DF (match_dup 7)))]
15825   "TARGET_USE_FANCY_MATH_387
15826    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15827    && flag_unsafe_math_optimizations"
15829   int i;
15831   for (i=2; i<8; i++)
15832     operands[i] = gen_reg_rtx (XFmode);
15834   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15837 (define_expand "asinsf2"
15838   [(set (match_dup 2)
15839         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15840    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15841    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15842    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15843    (parallel [(set (match_dup 7)
15844                    (unspec:XF [(match_dup 6) (match_dup 2)]
15845                               UNSPEC_FPATAN))
15846               (clobber (match_scratch:XF 8 ""))])
15847    (set (match_operand:SF 0 "register_operand" "")
15848         (float_truncate:SF (match_dup 7)))]
15849   "TARGET_USE_FANCY_MATH_387
15850    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15851    && flag_unsafe_math_optimizations"
15853   int i;
15855   for (i=2; i<8; i++)
15856     operands[i] = gen_reg_rtx (XFmode);
15858   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15861 (define_expand "asinxf2"
15862   [(set (match_dup 2)
15863         (mult:XF (match_operand:XF 1 "register_operand" "")
15864                  (match_dup 1)))
15865    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15866    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15867    (parallel [(set (match_operand:XF 0 "register_operand" "")
15868                    (unspec:XF [(match_dup 5) (match_dup 1)]
15869                               UNSPEC_FPATAN))
15870               (clobber (match_scratch:XF 6 ""))])]
15871   "TARGET_USE_FANCY_MATH_387
15872    && flag_unsafe_math_optimizations"
15874   int i;
15876   for (i=2; i<6; i++)
15877     operands[i] = gen_reg_rtx (XFmode);
15879   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15882 (define_expand "acosdf2"
15883   [(set (match_dup 2)
15884         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15885    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15886    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15887    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15888    (parallel [(set (match_dup 7)
15889                    (unspec:XF [(match_dup 2) (match_dup 6)]
15890                               UNSPEC_FPATAN))
15891               (clobber (match_scratch:XF 8 ""))])
15892    (set (match_operand:DF 0 "register_operand" "")
15893         (float_truncate:DF (match_dup 7)))]
15894   "TARGET_USE_FANCY_MATH_387
15895    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15896    && flag_unsafe_math_optimizations"
15898   int i;
15900   for (i=2; i<8; i++)
15901     operands[i] = gen_reg_rtx (XFmode);
15903   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15906 (define_expand "acossf2"
15907   [(set (match_dup 2)
15908         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15909    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15910    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15911    (set (match_dup 6) (sqrt:XF (match_dup 5)))
15912    (parallel [(set (match_dup 7)
15913                    (unspec:XF [(match_dup 2) (match_dup 6)]
15914                               UNSPEC_FPATAN))
15915               (clobber (match_scratch:XF 8 ""))])
15916    (set (match_operand:SF 0 "register_operand" "")
15917         (float_truncate:SF (match_dup 7)))]
15918   "TARGET_USE_FANCY_MATH_387
15919    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15920    && flag_unsafe_math_optimizations"
15922   int i;
15924   for (i=2; i<8; i++)
15925     operands[i] = gen_reg_rtx (XFmode);
15927   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
15930 (define_expand "acosxf2"
15931   [(set (match_dup 2)
15932         (mult:XF (match_operand:XF 1 "register_operand" "")
15933                  (match_dup 1)))
15934    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15935    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15936    (parallel [(set (match_operand:XF 0 "register_operand" "")
15937                    (unspec:XF [(match_dup 1) (match_dup 5)]
15938                               UNSPEC_FPATAN))
15939               (clobber (match_scratch:XF 6 ""))])]
15940   "TARGET_USE_FANCY_MATH_387
15941    && flag_unsafe_math_optimizations"
15943   int i;
15945   for (i=2; i<6; i++)
15946     operands[i] = gen_reg_rtx (XFmode);
15948   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15951 (define_insn "fyl2x_xf3"
15952   [(set (match_operand:XF 0 "register_operand" "=f")
15953         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15954                     (match_operand:XF 1 "register_operand" "u")]
15955                    UNSPEC_FYL2X))
15956    (clobber (match_scratch:XF 3 "=1"))]
15957   "TARGET_USE_FANCY_MATH_387
15958    && flag_unsafe_math_optimizations"
15959   "fyl2x"
15960   [(set_attr "type" "fpspc")
15961    (set_attr "mode" "XF")])
15963 (define_expand "logsf2"
15964   [(set (match_dup 2)
15965         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15966    (parallel [(set (match_dup 4)
15967                    (unspec:XF [(match_dup 2)
15968                                (match_dup 3)] UNSPEC_FYL2X))
15969               (clobber (match_scratch:XF 5 ""))])
15970    (set (match_operand:SF 0 "register_operand" "")
15971         (float_truncate:SF (match_dup 4)))]
15972   "TARGET_USE_FANCY_MATH_387
15973    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15974    && flag_unsafe_math_optimizations"
15976   rtx temp;
15978   operands[2] = gen_reg_rtx (XFmode);
15979   operands[3] = gen_reg_rtx (XFmode);
15980   operands[4] = gen_reg_rtx (XFmode);
15982   temp = standard_80387_constant_rtx (4); /* fldln2 */
15983   emit_move_insn (operands[3], temp);
15986 (define_expand "logdf2"
15987   [(set (match_dup 2)
15988         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15989    (parallel [(set (match_dup 4)
15990                    (unspec:XF [(match_dup 2)
15991                                (match_dup 3)] UNSPEC_FYL2X))
15992               (clobber (match_scratch:XF 5 ""))])
15993    (set (match_operand:DF 0 "register_operand" "")
15994         (float_truncate:DF (match_dup 4)))]
15995   "TARGET_USE_FANCY_MATH_387
15996    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15997    && flag_unsafe_math_optimizations"
15999   rtx temp;
16001   operands[2] = gen_reg_rtx (XFmode);
16002   operands[3] = gen_reg_rtx (XFmode);
16003   operands[4] = gen_reg_rtx (XFmode);
16005   temp = standard_80387_constant_rtx (4); /* fldln2 */
16006   emit_move_insn (operands[3], temp);
16009 (define_expand "logxf2"
16010   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16011                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16012                                (match_dup 2)] UNSPEC_FYL2X))
16013               (clobber (match_scratch:XF 3 ""))])]
16014   "TARGET_USE_FANCY_MATH_387
16015    && flag_unsafe_math_optimizations"
16017   rtx temp;
16019   operands[2] = gen_reg_rtx (XFmode);
16020   temp = standard_80387_constant_rtx (4); /* fldln2 */
16021   emit_move_insn (operands[2], temp);
16024 (define_expand "log10sf2"
16025   [(set (match_dup 2)
16026         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16027    (parallel [(set (match_dup 4)
16028                    (unspec:XF [(match_dup 2)
16029                                (match_dup 3)] UNSPEC_FYL2X))
16030               (clobber (match_scratch:XF 5 ""))])
16031    (set (match_operand:SF 0 "register_operand" "")
16032         (float_truncate:SF (match_dup 4)))]
16033   "TARGET_USE_FANCY_MATH_387
16034    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16035    && flag_unsafe_math_optimizations"
16037   rtx temp;
16039   operands[2] = gen_reg_rtx (XFmode);
16040   operands[3] = gen_reg_rtx (XFmode);
16041   operands[4] = gen_reg_rtx (XFmode);
16043   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16044   emit_move_insn (operands[3], temp);
16047 (define_expand "log10df2"
16048   [(set (match_dup 2)
16049         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16050    (parallel [(set (match_dup 4)
16051                    (unspec:XF [(match_dup 2)
16052                                (match_dup 3)] UNSPEC_FYL2X))
16053               (clobber (match_scratch:XF 5 ""))])
16054    (set (match_operand:DF 0 "register_operand" "")
16055         (float_truncate:DF (match_dup 4)))]
16056   "TARGET_USE_FANCY_MATH_387
16057    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16058    && flag_unsafe_math_optimizations"
16060   rtx temp;
16062   operands[2] = gen_reg_rtx (XFmode);
16063   operands[3] = gen_reg_rtx (XFmode);
16064   operands[4] = gen_reg_rtx (XFmode);
16066   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16067   emit_move_insn (operands[3], temp);
16070 (define_expand "log10xf2"
16071   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16072                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16073                                (match_dup 2)] UNSPEC_FYL2X))
16074               (clobber (match_scratch:XF 3 ""))])]
16075   "TARGET_USE_FANCY_MATH_387
16076    && flag_unsafe_math_optimizations"
16078   rtx temp;
16080   operands[2] = gen_reg_rtx (XFmode);
16081   temp = standard_80387_constant_rtx (3); /* fldlg2 */
16082   emit_move_insn (operands[2], temp);
16085 (define_expand "log2sf2"
16086   [(set (match_dup 2)
16087         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16088    (parallel [(set (match_dup 4)
16089                    (unspec:XF [(match_dup 2)
16090                                (match_dup 3)] UNSPEC_FYL2X))
16091               (clobber (match_scratch:XF 5 ""))])
16092    (set (match_operand:SF 0 "register_operand" "")
16093         (float_truncate:SF (match_dup 4)))]
16094   "TARGET_USE_FANCY_MATH_387
16095    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16096    && flag_unsafe_math_optimizations"
16098   operands[2] = gen_reg_rtx (XFmode);
16099   operands[3] = gen_reg_rtx (XFmode);
16100   operands[4] = gen_reg_rtx (XFmode);
16102   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16105 (define_expand "log2df2"
16106   [(set (match_dup 2)
16107         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16108    (parallel [(set (match_dup 4)
16109                    (unspec:XF [(match_dup 2)
16110                                (match_dup 3)] UNSPEC_FYL2X))
16111               (clobber (match_scratch:XF 5 ""))])
16112    (set (match_operand:DF 0 "register_operand" "")
16113         (float_truncate:DF (match_dup 4)))]
16114   "TARGET_USE_FANCY_MATH_387
16115    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16116    && flag_unsafe_math_optimizations"
16118   operands[2] = gen_reg_rtx (XFmode);
16119   operands[3] = gen_reg_rtx (XFmode);
16120   operands[4] = gen_reg_rtx (XFmode);
16122   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16125 (define_expand "log2xf2"
16126   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16127                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16128                                (match_dup 2)] UNSPEC_FYL2X))
16129               (clobber (match_scratch:XF 3 ""))])]
16130   "TARGET_USE_FANCY_MATH_387
16131    && flag_unsafe_math_optimizations"
16133   operands[2] = gen_reg_rtx (XFmode);
16134   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16137 (define_insn "fyl2xp1_xf3"
16138   [(set (match_operand:XF 0 "register_operand" "=f")
16139         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16140                     (match_operand:XF 1 "register_operand" "u")]
16141                    UNSPEC_FYL2XP1))
16142    (clobber (match_scratch:XF 3 "=1"))]
16143   "TARGET_USE_FANCY_MATH_387
16144    && flag_unsafe_math_optimizations"
16145   "fyl2xp1"
16146   [(set_attr "type" "fpspc")
16147    (set_attr "mode" "XF")])
16149 (define_expand "log1psf2"
16150   [(use (match_operand:SF 0 "register_operand" ""))
16151    (use (match_operand:SF 1 "register_operand" ""))]
16152   "TARGET_USE_FANCY_MATH_387
16153    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16154    && flag_unsafe_math_optimizations"
16156   rtx op0 = gen_reg_rtx (XFmode);
16157   rtx op1 = gen_reg_rtx (XFmode);
16159   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16160   ix86_emit_i387_log1p (op0, op1);
16161   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16162   DONE;
16165 (define_expand "log1pdf2"
16166   [(use (match_operand:DF 0 "register_operand" ""))
16167    (use (match_operand:DF 1 "register_operand" ""))]
16168   "TARGET_USE_FANCY_MATH_387
16169    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16170    && flag_unsafe_math_optimizations"
16172   rtx op0 = gen_reg_rtx (XFmode);
16173   rtx op1 = gen_reg_rtx (XFmode);
16175   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16176   ix86_emit_i387_log1p (op0, op1);
16177   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16178   DONE;
16181 (define_expand "log1pxf2"
16182   [(use (match_operand:XF 0 "register_operand" ""))
16183    (use (match_operand:XF 1 "register_operand" ""))]
16184   "TARGET_USE_FANCY_MATH_387
16185    && flag_unsafe_math_optimizations"
16187   ix86_emit_i387_log1p (operands[0], operands[1]);
16188   DONE;
16191 (define_insn "*fxtractxf3"
16192   [(set (match_operand:XF 0 "register_operand" "=f")
16193         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16194                    UNSPEC_XTRACT_FRACT))
16195    (set (match_operand:XF 1 "register_operand" "=u")
16196         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16197   "TARGET_USE_FANCY_MATH_387
16198    && flag_unsafe_math_optimizations"
16199   "fxtract"
16200   [(set_attr "type" "fpspc")
16201    (set_attr "mode" "XF")])
16203 (define_expand "logbsf2"
16204   [(set (match_dup 2)
16205         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16206    (parallel [(set (match_dup 3)
16207                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16208               (set (match_dup 4)
16209                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16210    (set (match_operand:SF 0 "register_operand" "")
16211         (float_truncate:SF (match_dup 4)))]
16212   "TARGET_USE_FANCY_MATH_387
16213    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16214    && flag_unsafe_math_optimizations"
16216   operands[2] = gen_reg_rtx (XFmode);
16217   operands[3] = gen_reg_rtx (XFmode);
16218   operands[4] = gen_reg_rtx (XFmode);
16221 (define_expand "logbdf2"
16222   [(set (match_dup 2)
16223         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16224    (parallel [(set (match_dup 3)
16225                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16226               (set (match_dup 4)
16227                    (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16228    (set (match_operand:DF 0 "register_operand" "")
16229         (float_truncate:DF (match_dup 4)))]
16230   "TARGET_USE_FANCY_MATH_387
16231    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16232    && flag_unsafe_math_optimizations"
16234   operands[2] = gen_reg_rtx (XFmode);
16235   operands[3] = gen_reg_rtx (XFmode);
16236   operands[4] = gen_reg_rtx (XFmode);
16239 (define_expand "logbxf2"
16240   [(parallel [(set (match_dup 2)
16241                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16242                               UNSPEC_XTRACT_FRACT))
16243               (set (match_operand:XF 0 "register_operand" "")
16244                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16245   "TARGET_USE_FANCY_MATH_387
16246    && flag_unsafe_math_optimizations"
16248   operands[2] = gen_reg_rtx (XFmode);
16251 (define_expand "ilogbsi2"
16252   [(parallel [(set (match_dup 2)
16253                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16254                               UNSPEC_XTRACT_FRACT))
16255               (set (match_operand:XF 3 "register_operand" "")
16256                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16257    (parallel [(set (match_operand:SI 0 "register_operand" "")
16258                    (fix:SI (match_dup 3)))
16259               (clobber (reg:CC FLAGS_REG))])]
16260   "TARGET_USE_FANCY_MATH_387
16261    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16262    && flag_unsafe_math_optimizations"
16264   operands[2] = gen_reg_rtx (XFmode);
16265   operands[3] = gen_reg_rtx (XFmode);
16268 (define_insn "*f2xm1xf2"
16269   [(set (match_operand:XF 0 "register_operand" "=f")
16270         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16271          UNSPEC_F2XM1))]
16272   "TARGET_USE_FANCY_MATH_387
16273    && flag_unsafe_math_optimizations"
16274   "f2xm1"
16275   [(set_attr "type" "fpspc")
16276    (set_attr "mode" "XF")])
16278 (define_insn "*fscalexf4"
16279   [(set (match_operand:XF 0 "register_operand" "=f")
16280         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16281                     (match_operand:XF 3 "register_operand" "1")]
16282                    UNSPEC_FSCALE_FRACT))
16283    (set (match_operand:XF 1 "register_operand" "=u")
16284         (unspec:XF [(match_dup 2) (match_dup 3)]
16285                    UNSPEC_FSCALE_EXP))]
16286   "TARGET_USE_FANCY_MATH_387
16287    && flag_unsafe_math_optimizations"
16288   "fscale"
16289   [(set_attr "type" "fpspc")
16290    (set_attr "mode" "XF")])
16292 (define_expand "expsf2"
16293   [(set (match_dup 2)
16294         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16295    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16296    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16297    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16298    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16299    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16300    (parallel [(set (match_dup 10)
16301                    (unspec:XF [(match_dup 9) (match_dup 5)]
16302                               UNSPEC_FSCALE_FRACT))
16303               (set (match_dup 11)
16304                    (unspec:XF [(match_dup 9) (match_dup 5)]
16305                               UNSPEC_FSCALE_EXP))])
16306    (set (match_operand:SF 0 "register_operand" "")
16307         (float_truncate:SF (match_dup 10)))]
16308   "TARGET_USE_FANCY_MATH_387
16309    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16310    && flag_unsafe_math_optimizations"
16312   rtx temp;
16313   int i;
16315   for (i=2; i<12; i++)
16316     operands[i] = gen_reg_rtx (XFmode);
16317   temp = standard_80387_constant_rtx (5); /* fldl2e */
16318   emit_move_insn (operands[3], temp);
16319   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16322 (define_expand "expdf2"
16323   [(set (match_dup 2)
16324         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16325    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16326    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16327    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16328    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16329    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16330    (parallel [(set (match_dup 10)
16331                    (unspec:XF [(match_dup 9) (match_dup 5)]
16332                               UNSPEC_FSCALE_FRACT))
16333               (set (match_dup 11)
16334                    (unspec:XF [(match_dup 9) (match_dup 5)]
16335                               UNSPEC_FSCALE_EXP))])
16336    (set (match_operand:DF 0 "register_operand" "")
16337         (float_truncate:DF (match_dup 10)))]
16338   "TARGET_USE_FANCY_MATH_387
16339    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16340    && flag_unsafe_math_optimizations"
16342   rtx temp;
16343   int i;
16345   for (i=2; i<12; i++)
16346     operands[i] = gen_reg_rtx (XFmode);
16347   temp = standard_80387_constant_rtx (5); /* fldl2e */
16348   emit_move_insn (operands[3], temp);
16349   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16352 (define_expand "expxf2"
16353   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16354                                (match_dup 2)))
16355    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16356    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16357    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16358    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16359    (parallel [(set (match_operand:XF 0 "register_operand" "")
16360                    (unspec:XF [(match_dup 8) (match_dup 4)]
16361                               UNSPEC_FSCALE_FRACT))
16362               (set (match_dup 9)
16363                    (unspec:XF [(match_dup 8) (match_dup 4)]
16364                               UNSPEC_FSCALE_EXP))])]
16365   "TARGET_USE_FANCY_MATH_387
16366    && flag_unsafe_math_optimizations"
16368   rtx temp;
16369   int i;
16371   for (i=2; i<10; i++)
16372     operands[i] = gen_reg_rtx (XFmode);
16373   temp = standard_80387_constant_rtx (5); /* fldl2e */
16374   emit_move_insn (operands[2], temp);
16375   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16378 (define_expand "exp10sf2"
16379   [(set (match_dup 2)
16380         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16381    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16382    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16383    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16384    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16385    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16386    (parallel [(set (match_dup 10)
16387                    (unspec:XF [(match_dup 9) (match_dup 5)]
16388                               UNSPEC_FSCALE_FRACT))
16389               (set (match_dup 11)
16390                    (unspec:XF [(match_dup 9) (match_dup 5)]
16391                               UNSPEC_FSCALE_EXP))])
16392    (set (match_operand:SF 0 "register_operand" "")
16393         (float_truncate:SF (match_dup 10)))]
16394   "TARGET_USE_FANCY_MATH_387
16395    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16396    && flag_unsafe_math_optimizations"
16398   rtx temp;
16399   int i;
16401   for (i=2; i<12; i++)
16402     operands[i] = gen_reg_rtx (XFmode);
16403   temp = standard_80387_constant_rtx (6); /* fldl2t */
16404   emit_move_insn (operands[3], temp);
16405   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16408 (define_expand "exp10df2"
16409   [(set (match_dup 2)
16410         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16411    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16412    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16413    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16414    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16415    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16416    (parallel [(set (match_dup 10)
16417                    (unspec:XF [(match_dup 9) (match_dup 5)]
16418                               UNSPEC_FSCALE_FRACT))
16419               (set (match_dup 11)
16420                    (unspec:XF [(match_dup 9) (match_dup 5)]
16421                               UNSPEC_FSCALE_EXP))])
16422    (set (match_operand:DF 0 "register_operand" "")
16423         (float_truncate:DF (match_dup 10)))]
16424   "TARGET_USE_FANCY_MATH_387
16425    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16426    && flag_unsafe_math_optimizations"
16428   rtx temp;
16429   int i;
16431   for (i=2; i<12; i++)
16432     operands[i] = gen_reg_rtx (XFmode);
16433   temp = standard_80387_constant_rtx (6); /* fldl2t */
16434   emit_move_insn (operands[3], temp);
16435   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16438 (define_expand "exp10xf2"
16439   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16440                                (match_dup 2)))
16441    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16442    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16443    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16444    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16445    (parallel [(set (match_operand:XF 0 "register_operand" "")
16446                    (unspec:XF [(match_dup 8) (match_dup 4)]
16447                               UNSPEC_FSCALE_FRACT))
16448               (set (match_dup 9)
16449                    (unspec:XF [(match_dup 8) (match_dup 4)]
16450                               UNSPEC_FSCALE_EXP))])]
16451   "TARGET_USE_FANCY_MATH_387
16452    && flag_unsafe_math_optimizations"
16454   rtx temp;
16455   int i;
16457   for (i=2; i<10; i++)
16458     operands[i] = gen_reg_rtx (XFmode);
16459   temp = standard_80387_constant_rtx (6); /* fldl2t */
16460   emit_move_insn (operands[2], temp);
16461   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16464 (define_expand "exp2sf2"
16465   [(set (match_dup 2)
16466         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16467    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16468    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16469    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16470    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16471    (parallel [(set (match_dup 8)
16472                    (unspec:XF [(match_dup 7) (match_dup 3)]
16473                               UNSPEC_FSCALE_FRACT))
16474               (set (match_dup 9)
16475                    (unspec:XF [(match_dup 7) (match_dup 3)]
16476                               UNSPEC_FSCALE_EXP))])
16477    (set (match_operand:SF 0 "register_operand" "")
16478         (float_truncate:SF (match_dup 8)))]
16479   "TARGET_USE_FANCY_MATH_387
16480    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16481    && flag_unsafe_math_optimizations"
16483   int i;
16485   for (i=2; i<10; i++)
16486     operands[i] = gen_reg_rtx (XFmode);
16487   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16490 (define_expand "exp2df2"
16491   [(set (match_dup 2)
16492         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16493    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16494    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16495    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16496    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16497    (parallel [(set (match_dup 8)
16498                    (unspec:XF [(match_dup 7) (match_dup 3)]
16499                               UNSPEC_FSCALE_FRACT))
16500               (set (match_dup 9)
16501                    (unspec:XF [(match_dup 7) (match_dup 3)]
16502                               UNSPEC_FSCALE_EXP))])
16503    (set (match_operand:DF 0 "register_operand" "")
16504         (float_truncate:DF (match_dup 8)))]
16505   "TARGET_USE_FANCY_MATH_387
16506    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16507    && flag_unsafe_math_optimizations"
16509   int i;
16511   for (i=2; i<10; i++)
16512     operands[i] = gen_reg_rtx (XFmode);
16513   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16516 (define_expand "exp2xf2"
16517   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16518    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16519    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16520    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16521    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16522    (parallel [(set (match_operand:XF 0 "register_operand" "")
16523                    (unspec:XF [(match_dup 7) (match_dup 3)]
16524                               UNSPEC_FSCALE_FRACT))
16525               (set (match_dup 8)
16526                    (unspec:XF [(match_dup 7) (match_dup 3)]
16527                               UNSPEC_FSCALE_EXP))])]
16528   "TARGET_USE_FANCY_MATH_387
16529    && flag_unsafe_math_optimizations"
16531   int i;
16533   for (i=2; i<9; i++)
16534     operands[i] = gen_reg_rtx (XFmode);
16535   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16538 (define_expand "expm1df2"
16539   [(set (match_dup 2)
16540         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16541    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16542    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16543    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16544    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16545    (parallel [(set (match_dup 8)
16546                    (unspec:XF [(match_dup 7) (match_dup 5)]
16547                               UNSPEC_FSCALE_FRACT))
16548                    (set (match_dup 9)
16549                    (unspec:XF [(match_dup 7) (match_dup 5)]
16550                               UNSPEC_FSCALE_EXP))])
16551    (parallel [(set (match_dup 11)
16552                    (unspec:XF [(match_dup 10) (match_dup 9)]
16553                               UNSPEC_FSCALE_FRACT))
16554               (set (match_dup 12)
16555                    (unspec:XF [(match_dup 10) (match_dup 9)]
16556                               UNSPEC_FSCALE_EXP))])
16557    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16558    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16559    (set (match_operand:DF 0 "register_operand" "")
16560         (float_truncate:DF (match_dup 14)))]
16561   "TARGET_USE_FANCY_MATH_387
16562    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16563    && flag_unsafe_math_optimizations"
16565   rtx temp;
16566   int i;
16568   for (i=2; i<15; i++)
16569     operands[i] = gen_reg_rtx (XFmode);
16570   temp = standard_80387_constant_rtx (5); /* fldl2e */
16571   emit_move_insn (operands[3], temp);
16572   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16575 (define_expand "expm1sf2"
16576   [(set (match_dup 2)
16577         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16578    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16579    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16580    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16581    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16582    (parallel [(set (match_dup 8)
16583                    (unspec:XF [(match_dup 7) (match_dup 5)]
16584                               UNSPEC_FSCALE_FRACT))
16585                    (set (match_dup 9)
16586                    (unspec:XF [(match_dup 7) (match_dup 5)]
16587                               UNSPEC_FSCALE_EXP))])
16588    (parallel [(set (match_dup 11)
16589                    (unspec:XF [(match_dup 10) (match_dup 9)]
16590                               UNSPEC_FSCALE_FRACT))
16591               (set (match_dup 12)
16592                    (unspec:XF [(match_dup 10) (match_dup 9)]
16593                               UNSPEC_FSCALE_EXP))])
16594    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16595    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16596    (set (match_operand:SF 0 "register_operand" "")
16597         (float_truncate:SF (match_dup 14)))]
16598   "TARGET_USE_FANCY_MATH_387
16599    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16600    && flag_unsafe_math_optimizations"
16602   rtx temp;
16603   int i;
16605   for (i=2; i<15; i++)
16606     operands[i] = gen_reg_rtx (XFmode);
16607   temp = standard_80387_constant_rtx (5); /* fldl2e */
16608   emit_move_insn (operands[3], temp);
16609   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16612 (define_expand "expm1xf2"
16613   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16614                                (match_dup 2)))
16615    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16616    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16617    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16618    (parallel [(set (match_dup 7)
16619                    (unspec:XF [(match_dup 6) (match_dup 4)]
16620                               UNSPEC_FSCALE_FRACT))
16621                    (set (match_dup 8)
16622                    (unspec:XF [(match_dup 6) (match_dup 4)]
16623                               UNSPEC_FSCALE_EXP))])
16624    (parallel [(set (match_dup 10)
16625                    (unspec:XF [(match_dup 9) (match_dup 8)]
16626                               UNSPEC_FSCALE_FRACT))
16627               (set (match_dup 11)
16628                    (unspec:XF [(match_dup 9) (match_dup 8)]
16629                               UNSPEC_FSCALE_EXP))])
16630    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16631    (set (match_operand:XF 0 "register_operand" "")
16632         (plus:XF (match_dup 12) (match_dup 7)))]
16633   "TARGET_USE_FANCY_MATH_387
16634    && flag_unsafe_math_optimizations"
16636   rtx temp;
16637   int i;
16639   for (i=2; i<13; i++)
16640     operands[i] = gen_reg_rtx (XFmode);
16641   temp = standard_80387_constant_rtx (5); /* fldl2e */
16642   emit_move_insn (operands[2], temp);
16643   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16646 (define_expand "ldexpdf3"
16647   [(set (match_dup 3)
16648         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16649    (set (match_dup 4)
16650         (float:XF (match_operand:SI 2 "register_operand" "")))
16651    (parallel [(set (match_dup 5)
16652                    (unspec:XF [(match_dup 3) (match_dup 4)]
16653                               UNSPEC_FSCALE_FRACT))
16654               (set (match_dup 6)
16655                    (unspec:XF [(match_dup 3) (match_dup 4)]
16656                               UNSPEC_FSCALE_EXP))])
16657    (set (match_operand:DF 0 "register_operand" "")
16658         (float_truncate:DF (match_dup 5)))]
16659   "TARGET_USE_FANCY_MATH_387
16660    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16661    && flag_unsafe_math_optimizations"
16663   int i;
16665   for (i=3; i<7; i++)
16666     operands[i] = gen_reg_rtx (XFmode);
16669 (define_expand "ldexpsf3"
16670   [(set (match_dup 3)
16671         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16672    (set (match_dup 4)
16673         (float:XF (match_operand:SI 2 "register_operand" "")))
16674    (parallel [(set (match_dup 5)
16675                    (unspec:XF [(match_dup 3) (match_dup 4)]
16676                               UNSPEC_FSCALE_FRACT))
16677               (set (match_dup 6)
16678                    (unspec:XF [(match_dup 3) (match_dup 4)]
16679                               UNSPEC_FSCALE_EXP))])
16680    (set (match_operand:SF 0 "register_operand" "")
16681         (float_truncate:SF (match_dup 5)))]
16682   "TARGET_USE_FANCY_MATH_387
16683    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16684    && flag_unsafe_math_optimizations"
16686   int i;
16688   for (i=3; i<7; i++)
16689     operands[i] = gen_reg_rtx (XFmode);
16692 (define_expand "ldexpxf3"
16693   [(set (match_dup 3)
16694         (float:XF (match_operand:SI 2 "register_operand" "")))
16695    (parallel [(set (match_operand:XF 0 " register_operand" "")
16696                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16697                                (match_dup 3)]
16698                               UNSPEC_FSCALE_FRACT))
16699               (set (match_dup 4)
16700                    (unspec:XF [(match_dup 1) (match_dup 3)]
16701                               UNSPEC_FSCALE_EXP))])]
16702   "TARGET_USE_FANCY_MATH_387
16703    && flag_unsafe_math_optimizations"
16705   int i;
16707   for (i=3; i<5; i++)
16708     operands[i] = gen_reg_rtx (XFmode);
16712 (define_insn "frndintxf2"
16713   [(set (match_operand:XF 0 "register_operand" "=f")
16714         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16715          UNSPEC_FRNDINT))]
16716   "TARGET_USE_FANCY_MATH_387
16717    && flag_unsafe_math_optimizations"
16718   "frndint"
16719   [(set_attr "type" "fpspc")
16720    (set_attr "mode" "XF")])
16722 (define_expand "rintdf2"
16723   [(use (match_operand:DF 0 "register_operand" ""))
16724    (use (match_operand:DF 1 "register_operand" ""))]
16725   "TARGET_USE_FANCY_MATH_387
16726    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16727    && flag_unsafe_math_optimizations"
16729   rtx op0 = gen_reg_rtx (XFmode);
16730   rtx op1 = gen_reg_rtx (XFmode);
16732   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16733   emit_insn (gen_frndintxf2 (op0, op1));
16735   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16736   DONE;
16739 (define_expand "rintsf2"
16740   [(use (match_operand:SF 0 "register_operand" ""))
16741    (use (match_operand:SF 1 "register_operand" ""))]
16742   "TARGET_USE_FANCY_MATH_387
16743    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16744    && flag_unsafe_math_optimizations"
16746   rtx op0 = gen_reg_rtx (XFmode);
16747   rtx op1 = gen_reg_rtx (XFmode);
16749   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16750   emit_insn (gen_frndintxf2 (op0, op1));
16752   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16753   DONE;
16756 (define_expand "rintxf2"
16757   [(use (match_operand:XF 0 "register_operand" ""))
16758    (use (match_operand:XF 1 "register_operand" ""))]
16759   "TARGET_USE_FANCY_MATH_387
16760    && flag_unsafe_math_optimizations"
16762   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16763   DONE;
16766 (define_insn_and_split "*fistdi2_1"
16767   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16768         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16769          UNSPEC_FIST))]
16770   "TARGET_USE_FANCY_MATH_387
16771    && flag_unsafe_math_optimizations
16772    && !(reload_completed || reload_in_progress)"
16773   "#"
16774   "&& 1"
16775   [(const_int 0)]
16777   if (memory_operand (operands[0], VOIDmode))
16778     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16779   else
16780     {
16781       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16782       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16783                                          operands[2]));
16784     }
16785   DONE;
16787   [(set_attr "type" "fpspc")
16788    (set_attr "mode" "DI")])
16790 (define_insn "fistdi2"
16791   [(set (match_operand:DI 0 "memory_operand" "=m")
16792         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16793          UNSPEC_FIST))
16794    (clobber (match_scratch:XF 2 "=&1f"))]
16795   "TARGET_USE_FANCY_MATH_387
16796    && flag_unsafe_math_optimizations"
16797   "* return output_fix_trunc (insn, operands, 0);"
16798   [(set_attr "type" "fpspc")
16799    (set_attr "mode" "DI")])
16801 (define_insn "fistdi2_with_temp"
16802   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16803         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16804          UNSPEC_FIST))
16805    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16806    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16807   "TARGET_USE_FANCY_MATH_387
16808    && flag_unsafe_math_optimizations"
16809   "#"
16810   [(set_attr "type" "fpspc")
16811    (set_attr "mode" "DI")])
16813 (define_split 
16814   [(set (match_operand:DI 0 "register_operand" "")
16815         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16816          UNSPEC_FIST))
16817    (clobber (match_operand:DI 2 "memory_operand" ""))
16818    (clobber (match_scratch 3 ""))]
16819   "reload_completed"
16820   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16821               (clobber (match_dup 3))])
16822    (set (match_dup 0) (match_dup 2))]
16823   "")
16825 (define_split 
16826   [(set (match_operand:DI 0 "memory_operand" "")
16827         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16828          UNSPEC_FIST))
16829    (clobber (match_operand:DI 2 "memory_operand" ""))
16830    (clobber (match_scratch 3 ""))]
16831   "reload_completed"
16832   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16833               (clobber (match_dup 3))])]
16834   "")
16836 (define_insn_and_split "*fist<mode>2_1"
16837   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16838         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16839          UNSPEC_FIST))]
16840   "TARGET_USE_FANCY_MATH_387
16841    && flag_unsafe_math_optimizations
16842    && !(reload_completed || reload_in_progress)"
16843   "#"
16844   "&& 1"
16845   [(const_int 0)]
16847   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16848   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16849                                         operands[2]));
16850   DONE;
16852   [(set_attr "type" "fpspc")
16853    (set_attr "mode" "<MODE>")])
16855 (define_insn "fist<mode>2"
16856   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16857         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16858          UNSPEC_FIST))]
16859   "TARGET_USE_FANCY_MATH_387
16860    && flag_unsafe_math_optimizations"
16861   "* return output_fix_trunc (insn, operands, 0);"
16862   [(set_attr "type" "fpspc")
16863    (set_attr "mode" "<MODE>")])
16865 (define_insn "fist<mode>2_with_temp"
16866   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16867         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16868          UNSPEC_FIST))
16869    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16870   "TARGET_USE_FANCY_MATH_387
16871    && flag_unsafe_math_optimizations"
16872   "#"
16873   [(set_attr "type" "fpspc")
16874    (set_attr "mode" "<MODE>")])
16876 (define_split 
16877   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16878         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16879          UNSPEC_FIST))
16880    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16881   "reload_completed"
16882   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16883                        UNSPEC_FIST))
16884    (set (match_dup 0) (match_dup 2))]
16885   "")
16887 (define_split 
16888   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16889         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16890          UNSPEC_FIST))
16891    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16892   "reload_completed"
16893   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16894                        UNSPEC_FIST))]
16895   "")
16897 (define_expand "lrint<mode>2"
16898   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16899         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16900          UNSPEC_FIST))]
16901   "TARGET_USE_FANCY_MATH_387
16902    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16903    && flag_unsafe_math_optimizations"
16904   "")
16906 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16907 (define_insn_and_split "frndintxf2_floor"
16908   [(set (match_operand:XF 0 "register_operand" "=f")
16909         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16910          UNSPEC_FRNDINT_FLOOR))
16911    (clobber (reg:CC FLAGS_REG))]
16912   "TARGET_USE_FANCY_MATH_387
16913    && flag_unsafe_math_optimizations
16914    && !(reload_completed || reload_in_progress)"
16915   "#"
16916   "&& 1"
16917   [(const_int 0)]
16919   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16921   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16922   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16924   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16925                                         operands[2], operands[3]));
16926   DONE;
16928   [(set_attr "type" "frndint")
16929    (set_attr "i387_cw" "floor")
16930    (set_attr "mode" "XF")])
16932 (define_insn "frndintxf2_floor_i387"
16933   [(set (match_operand:XF 0 "register_operand" "=f")
16934         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16935          UNSPEC_FRNDINT_FLOOR))
16936    (use (match_operand:HI 2 "memory_operand" "m"))
16937    (use (match_operand:HI 3 "memory_operand" "m"))]
16938   "TARGET_USE_FANCY_MATH_387
16939    && flag_unsafe_math_optimizations"
16940   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16941   [(set_attr "type" "frndint")
16942    (set_attr "i387_cw" "floor")
16943    (set_attr "mode" "XF")])
16945 (define_expand "floorxf2"
16946   [(use (match_operand:XF 0 "register_operand" ""))
16947    (use (match_operand:XF 1 "register_operand" ""))]
16948   "TARGET_USE_FANCY_MATH_387
16949    && flag_unsafe_math_optimizations"
16951   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16952   DONE;
16955 (define_expand "floordf2"
16956   [(use (match_operand:DF 0 "register_operand" ""))
16957    (use (match_operand:DF 1 "register_operand" ""))]
16958   "TARGET_USE_FANCY_MATH_387
16959    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16960    && flag_unsafe_math_optimizations"
16962   rtx op0 = gen_reg_rtx (XFmode);
16963   rtx op1 = gen_reg_rtx (XFmode);
16965   emit_insn (gen_extenddfxf2 (op1, operands[1]));
16966   emit_insn (gen_frndintxf2_floor (op0, op1));
16968   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16969   DONE;
16972 (define_expand "floorsf2"
16973   [(use (match_operand:SF 0 "register_operand" ""))
16974    (use (match_operand:SF 1 "register_operand" ""))]
16975   "TARGET_USE_FANCY_MATH_387
16976    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16977    && flag_unsafe_math_optimizations"
16979   rtx op0 = gen_reg_rtx (XFmode);
16980   rtx op1 = gen_reg_rtx (XFmode);
16982   emit_insn (gen_extendsfxf2 (op1, operands[1]));
16983   emit_insn (gen_frndintxf2_floor (op0, op1));
16985   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16986   DONE;
16989 (define_insn_and_split "*fist<mode>2_floor_1"
16990   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16991         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16992          UNSPEC_FIST_FLOOR))
16993    (clobber (reg:CC FLAGS_REG))]
16994   "TARGET_USE_FANCY_MATH_387
16995    && flag_unsafe_math_optimizations
16996    && !(reload_completed || reload_in_progress)"
16997   "#"
16998   "&& 1"
16999   [(const_int 0)]
17001   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17003   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17004   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17005   if (memory_operand (operands[0], VOIDmode))
17006     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17007                                       operands[2], operands[3]));
17008   else
17009     {
17010       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17011       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17012                                                   operands[2], operands[3],
17013                                                   operands[4]));
17014     }
17015   DONE;
17017   [(set_attr "type" "fistp")
17018    (set_attr "i387_cw" "floor")
17019    (set_attr "mode" "<MODE>")])
17021 (define_insn "fistdi2_floor"
17022   [(set (match_operand:DI 0 "memory_operand" "=m")
17023         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17024          UNSPEC_FIST_FLOOR))
17025    (use (match_operand:HI 2 "memory_operand" "m"))
17026    (use (match_operand:HI 3 "memory_operand" "m"))
17027    (clobber (match_scratch:XF 4 "=&1f"))]
17028   "TARGET_USE_FANCY_MATH_387
17029    && flag_unsafe_math_optimizations"
17030   "* return output_fix_trunc (insn, operands, 0);"
17031   [(set_attr "type" "fistp")
17032    (set_attr "i387_cw" "floor")
17033    (set_attr "mode" "DI")])
17035 (define_insn "fistdi2_floor_with_temp"
17036   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17037         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17038          UNSPEC_FIST_FLOOR))
17039    (use (match_operand:HI 2 "memory_operand" "m,m"))
17040    (use (match_operand:HI 3 "memory_operand" "m,m"))
17041    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17042    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17043   "TARGET_USE_FANCY_MATH_387
17044    && flag_unsafe_math_optimizations"
17045   "#"
17046   [(set_attr "type" "fistp")
17047    (set_attr "i387_cw" "floor")
17048    (set_attr "mode" "DI")])
17050 (define_split 
17051   [(set (match_operand:DI 0 "register_operand" "")
17052         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17053          UNSPEC_FIST_FLOOR))
17054    (use (match_operand:HI 2 "memory_operand" ""))
17055    (use (match_operand:HI 3 "memory_operand" ""))
17056    (clobber (match_operand:DI 4 "memory_operand" ""))
17057    (clobber (match_scratch 5 ""))]
17058   "reload_completed"
17059   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17060               (use (match_dup 2))
17061               (use (match_dup 3))
17062               (clobber (match_dup 5))])
17063    (set (match_dup 0) (match_dup 4))]
17064   "")
17066 (define_split 
17067   [(set (match_operand:DI 0 "memory_operand" "")
17068         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17069          UNSPEC_FIST_FLOOR))
17070    (use (match_operand:HI 2 "memory_operand" ""))
17071    (use (match_operand:HI 3 "memory_operand" ""))
17072    (clobber (match_operand:DI 4 "memory_operand" ""))
17073    (clobber (match_scratch 5 ""))]
17074   "reload_completed"
17075   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17076               (use (match_dup 2))
17077               (use (match_dup 3))
17078               (clobber (match_dup 5))])]
17079   "")
17081 (define_insn "fist<mode>2_floor"
17082   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17083         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17084          UNSPEC_FIST_FLOOR))
17085    (use (match_operand:HI 2 "memory_operand" "m"))
17086    (use (match_operand:HI 3 "memory_operand" "m"))]
17087   "TARGET_USE_FANCY_MATH_387
17088    && flag_unsafe_math_optimizations"
17089   "* return output_fix_trunc (insn, operands, 0);"
17090   [(set_attr "type" "fistp")
17091    (set_attr "i387_cw" "floor")
17092    (set_attr "mode" "<MODE>")])
17094 (define_insn "fist<mode>2_floor_with_temp"
17095   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17096         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17097          UNSPEC_FIST_FLOOR))
17098    (use (match_operand:HI 2 "memory_operand" "m,m"))
17099    (use (match_operand:HI 3 "memory_operand" "m,m"))
17100    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17101   "TARGET_USE_FANCY_MATH_387
17102    && flag_unsafe_math_optimizations"
17103   "#"
17104   [(set_attr "type" "fistp")
17105    (set_attr "i387_cw" "floor")
17106    (set_attr "mode" "<MODE>")])
17108 (define_split 
17109   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17110         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17111          UNSPEC_FIST_FLOOR))
17112    (use (match_operand:HI 2 "memory_operand" ""))
17113    (use (match_operand:HI 3 "memory_operand" ""))
17114    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17115   "reload_completed"
17116   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17117                                   UNSPEC_FIST_FLOOR))
17118               (use (match_dup 2))
17119               (use (match_dup 3))])
17120    (set (match_dup 0) (match_dup 4))]
17121   "")
17123 (define_split 
17124   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17125         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17126          UNSPEC_FIST_FLOOR))
17127    (use (match_operand:HI 2 "memory_operand" ""))
17128    (use (match_operand:HI 3 "memory_operand" ""))
17129    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17130   "reload_completed"
17131   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17132                                   UNSPEC_FIST_FLOOR))
17133               (use (match_dup 2))
17134               (use (match_dup 3))])]
17135   "")
17137 (define_expand "lfloor<mode>2"
17138   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17139                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17140                     UNSPEC_FIST_FLOOR))
17141               (clobber (reg:CC FLAGS_REG))])]
17142   "TARGET_USE_FANCY_MATH_387
17143    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17144    && flag_unsafe_math_optimizations"
17145   "")
17147 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17148 (define_insn_and_split "frndintxf2_ceil"
17149   [(set (match_operand:XF 0 "register_operand" "=f")
17150         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17151          UNSPEC_FRNDINT_CEIL))
17152    (clobber (reg:CC FLAGS_REG))]
17153   "TARGET_USE_FANCY_MATH_387
17154    && flag_unsafe_math_optimizations
17155    && !(reload_completed || reload_in_progress)"
17156   "#"
17157   "&& 1"
17158   [(const_int 0)]
17160   ix86_optimize_mode_switching[I387_CEIL] = 1;
17162   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17163   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17165   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17166                                        operands[2], operands[3]));
17167   DONE;
17169   [(set_attr "type" "frndint")
17170    (set_attr "i387_cw" "ceil")
17171    (set_attr "mode" "XF")])
17173 (define_insn "frndintxf2_ceil_i387"
17174   [(set (match_operand:XF 0 "register_operand" "=f")
17175         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17176          UNSPEC_FRNDINT_CEIL))
17177    (use (match_operand:HI 2 "memory_operand" "m"))
17178    (use (match_operand:HI 3 "memory_operand" "m"))]
17179   "TARGET_USE_FANCY_MATH_387
17180    && flag_unsafe_math_optimizations"
17181   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17182   [(set_attr "type" "frndint")
17183    (set_attr "i387_cw" "ceil")
17184    (set_attr "mode" "XF")])
17186 (define_expand "ceilxf2"
17187   [(use (match_operand:XF 0 "register_operand" ""))
17188    (use (match_operand:XF 1 "register_operand" ""))]
17189   "TARGET_USE_FANCY_MATH_387
17190    && flag_unsafe_math_optimizations"
17192   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17193   DONE;
17196 (define_expand "ceildf2"
17197   [(use (match_operand:DF 0 "register_operand" ""))
17198    (use (match_operand:DF 1 "register_operand" ""))]
17199   "TARGET_USE_FANCY_MATH_387
17200    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17201    && flag_unsafe_math_optimizations"
17203   rtx op0 = gen_reg_rtx (XFmode);
17204   rtx op1 = gen_reg_rtx (XFmode);
17206   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17207   emit_insn (gen_frndintxf2_ceil (op0, op1));
17209   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17210   DONE;
17213 (define_expand "ceilsf2"
17214   [(use (match_operand:SF 0 "register_operand" ""))
17215    (use (match_operand:SF 1 "register_operand" ""))]
17216   "TARGET_USE_FANCY_MATH_387
17217    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17218    && flag_unsafe_math_optimizations"
17220   rtx op0 = gen_reg_rtx (XFmode);
17221   rtx op1 = gen_reg_rtx (XFmode);
17223   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17224   emit_insn (gen_frndintxf2_ceil (op0, op1));
17226   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17227   DONE;
17230 (define_insn_and_split "*fist<mode>2_ceil_1"
17231   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17232         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17233          UNSPEC_FIST_CEIL))
17234    (clobber (reg:CC FLAGS_REG))]
17235   "TARGET_USE_FANCY_MATH_387
17236    && flag_unsafe_math_optimizations
17237    && !(reload_completed || reload_in_progress)"
17238   "#"
17239   "&& 1"
17240   [(const_int 0)]
17242   ix86_optimize_mode_switching[I387_CEIL] = 1;
17244   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17245   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17246   if (memory_operand (operands[0], VOIDmode))
17247     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17248                                      operands[2], operands[3]));
17249   else
17250     {
17251       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17252       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17253                                                  operands[2], operands[3],
17254                                                  operands[4]));
17255     }
17256   DONE;
17258   [(set_attr "type" "fistp")
17259    (set_attr "i387_cw" "ceil")
17260    (set_attr "mode" "<MODE>")])
17262 (define_insn "fistdi2_ceil"
17263   [(set (match_operand:DI 0 "memory_operand" "=m")
17264         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17265          UNSPEC_FIST_CEIL))
17266    (use (match_operand:HI 2 "memory_operand" "m"))
17267    (use (match_operand:HI 3 "memory_operand" "m"))
17268    (clobber (match_scratch:XF 4 "=&1f"))]
17269   "TARGET_USE_FANCY_MATH_387
17270    && flag_unsafe_math_optimizations"
17271   "* return output_fix_trunc (insn, operands, 0);"
17272   [(set_attr "type" "fistp")
17273    (set_attr "i387_cw" "ceil")
17274    (set_attr "mode" "DI")])
17276 (define_insn "fistdi2_ceil_with_temp"
17277   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17278         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17279          UNSPEC_FIST_CEIL))
17280    (use (match_operand:HI 2 "memory_operand" "m,m"))
17281    (use (match_operand:HI 3 "memory_operand" "m,m"))
17282    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17283    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17284   "TARGET_USE_FANCY_MATH_387
17285    && flag_unsafe_math_optimizations"
17286   "#"
17287   [(set_attr "type" "fistp")
17288    (set_attr "i387_cw" "ceil")
17289    (set_attr "mode" "DI")])
17291 (define_split 
17292   [(set (match_operand:DI 0 "register_operand" "")
17293         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17294          UNSPEC_FIST_CEIL))
17295    (use (match_operand:HI 2 "memory_operand" ""))
17296    (use (match_operand:HI 3 "memory_operand" ""))
17297    (clobber (match_operand:DI 4 "memory_operand" ""))
17298    (clobber (match_scratch 5 ""))]
17299   "reload_completed"
17300   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17301               (use (match_dup 2))
17302               (use (match_dup 3))
17303               (clobber (match_dup 5))])
17304    (set (match_dup 0) (match_dup 4))]
17305   "")
17307 (define_split 
17308   [(set (match_operand:DI 0 "memory_operand" "")
17309         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17310          UNSPEC_FIST_CEIL))
17311    (use (match_operand:HI 2 "memory_operand" ""))
17312    (use (match_operand:HI 3 "memory_operand" ""))
17313    (clobber (match_operand:DI 4 "memory_operand" ""))
17314    (clobber (match_scratch 5 ""))]
17315   "reload_completed"
17316   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17317               (use (match_dup 2))
17318               (use (match_dup 3))
17319               (clobber (match_dup 5))])]
17320   "")
17322 (define_insn "fist<mode>2_ceil"
17323   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17324         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17325          UNSPEC_FIST_CEIL))
17326    (use (match_operand:HI 2 "memory_operand" "m"))
17327    (use (match_operand:HI 3 "memory_operand" "m"))]
17328   "TARGET_USE_FANCY_MATH_387
17329    && flag_unsafe_math_optimizations"
17330   "* return output_fix_trunc (insn, operands, 0);"
17331   [(set_attr "type" "fistp")
17332    (set_attr "i387_cw" "ceil")
17333    (set_attr "mode" "<MODE>")])
17335 (define_insn "fist<mode>2_ceil_with_temp"
17336   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17337         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17338          UNSPEC_FIST_CEIL))
17339    (use (match_operand:HI 2 "memory_operand" "m,m"))
17340    (use (match_operand:HI 3 "memory_operand" "m,m"))
17341    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17342   "TARGET_USE_FANCY_MATH_387
17343    && flag_unsafe_math_optimizations"
17344   "#"
17345   [(set_attr "type" "fistp")
17346    (set_attr "i387_cw" "ceil")
17347    (set_attr "mode" "<MODE>")])
17349 (define_split 
17350   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17351         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17352          UNSPEC_FIST_CEIL))
17353    (use (match_operand:HI 2 "memory_operand" ""))
17354    (use (match_operand:HI 3 "memory_operand" ""))
17355    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17356   "reload_completed"
17357   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17358                                   UNSPEC_FIST_CEIL))
17359               (use (match_dup 2))
17360               (use (match_dup 3))])
17361    (set (match_dup 0) (match_dup 4))]
17362   "")
17364 (define_split 
17365   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17366         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17367          UNSPEC_FIST_CEIL))
17368    (use (match_operand:HI 2 "memory_operand" ""))
17369    (use (match_operand:HI 3 "memory_operand" ""))
17370    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17371   "reload_completed"
17372   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17373                                   UNSPEC_FIST_CEIL))
17374               (use (match_dup 2))
17375               (use (match_dup 3))])]
17376   "")
17378 (define_expand "lceil<mode>2"
17379   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17380                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17381                     UNSPEC_FIST_CEIL))
17382               (clobber (reg:CC FLAGS_REG))])]
17383   "TARGET_USE_FANCY_MATH_387
17384    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17385    && flag_unsafe_math_optimizations"
17386   "")
17388 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17389 (define_insn_and_split "frndintxf2_trunc"
17390   [(set (match_operand:XF 0 "register_operand" "=f")
17391         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17392          UNSPEC_FRNDINT_TRUNC))
17393    (clobber (reg:CC FLAGS_REG))]
17394   "TARGET_USE_FANCY_MATH_387
17395    && flag_unsafe_math_optimizations
17396    && !(reload_completed || reload_in_progress)"
17397   "#"
17398   "&& 1"
17399   [(const_int 0)]
17401   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17403   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17404   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17406   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17407                                         operands[2], operands[3]));
17408   DONE;
17410   [(set_attr "type" "frndint")
17411    (set_attr "i387_cw" "trunc")
17412    (set_attr "mode" "XF")])
17414 (define_insn "frndintxf2_trunc_i387"
17415   [(set (match_operand:XF 0 "register_operand" "=f")
17416         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17417          UNSPEC_FRNDINT_TRUNC))
17418    (use (match_operand:HI 2 "memory_operand" "m"))
17419    (use (match_operand:HI 3 "memory_operand" "m"))]
17420   "TARGET_USE_FANCY_MATH_387
17421    && flag_unsafe_math_optimizations"
17422   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17423   [(set_attr "type" "frndint")
17424    (set_attr "i387_cw" "trunc")
17425    (set_attr "mode" "XF")])
17427 (define_expand "btruncxf2"
17428   [(use (match_operand:XF 0 "register_operand" ""))
17429    (use (match_operand:XF 1 "register_operand" ""))]
17430   "TARGET_USE_FANCY_MATH_387
17431    && flag_unsafe_math_optimizations"
17433   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17434   DONE;
17437 (define_expand "btruncdf2"
17438   [(use (match_operand:DF 0 "register_operand" ""))
17439    (use (match_operand:DF 1 "register_operand" ""))]
17440   "TARGET_USE_FANCY_MATH_387
17441    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17442    && flag_unsafe_math_optimizations"
17444   rtx op0 = gen_reg_rtx (XFmode);
17445   rtx op1 = gen_reg_rtx (XFmode);
17447   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17448   emit_insn (gen_frndintxf2_trunc (op0, op1));
17450   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17451   DONE;
17454 (define_expand "btruncsf2"
17455   [(use (match_operand:SF 0 "register_operand" ""))
17456    (use (match_operand:SF 1 "register_operand" ""))]
17457   "TARGET_USE_FANCY_MATH_387
17458    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17459    && flag_unsafe_math_optimizations"
17461   rtx op0 = gen_reg_rtx (XFmode);
17462   rtx op1 = gen_reg_rtx (XFmode);
17464   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17465   emit_insn (gen_frndintxf2_trunc (op0, op1));
17467   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17468   DONE;
17471 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17472 (define_insn_and_split "frndintxf2_mask_pm"
17473   [(set (match_operand:XF 0 "register_operand" "=f")
17474         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17475          UNSPEC_FRNDINT_MASK_PM))
17476    (clobber (reg:CC FLAGS_REG))]
17477   "TARGET_USE_FANCY_MATH_387
17478    && flag_unsafe_math_optimizations
17479    && !(reload_completed || reload_in_progress)"
17480   "#"
17481   "&& 1"
17482   [(const_int 0)]
17484   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17486   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17487   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17489   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17490                                           operands[2], operands[3]));
17491   DONE;
17493   [(set_attr "type" "frndint")
17494    (set_attr "i387_cw" "mask_pm")
17495    (set_attr "mode" "XF")])
17497 (define_insn "frndintxf2_mask_pm_i387"
17498   [(set (match_operand:XF 0 "register_operand" "=f")
17499         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17500          UNSPEC_FRNDINT_MASK_PM))
17501    (use (match_operand:HI 2 "memory_operand" "m"))
17502    (use (match_operand:HI 3 "memory_operand" "m"))]
17503   "TARGET_USE_FANCY_MATH_387
17504    && flag_unsafe_math_optimizations"
17505   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17506   [(set_attr "type" "frndint")
17507    (set_attr "i387_cw" "mask_pm")
17508    (set_attr "mode" "XF")])
17510 (define_expand "nearbyintxf2"
17511   [(use (match_operand:XF 0 "register_operand" ""))
17512    (use (match_operand:XF 1 "register_operand" ""))]
17513   "TARGET_USE_FANCY_MATH_387
17514    && flag_unsafe_math_optimizations"
17516   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17518   DONE;
17521 (define_expand "nearbyintdf2"
17522   [(use (match_operand:DF 0 "register_operand" ""))
17523    (use (match_operand:DF 1 "register_operand" ""))]
17524   "TARGET_USE_FANCY_MATH_387
17525    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17526    && flag_unsafe_math_optimizations"
17528   rtx op0 = gen_reg_rtx (XFmode);
17529   rtx op1 = gen_reg_rtx (XFmode);
17531   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17532   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17534   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17535   DONE;
17538 (define_expand "nearbyintsf2"
17539   [(use (match_operand:SF 0 "register_operand" ""))
17540    (use (match_operand:SF 1 "register_operand" ""))]
17541   "TARGET_USE_FANCY_MATH_387
17542    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17543    && flag_unsafe_math_optimizations"
17545   rtx op0 = gen_reg_rtx (XFmode);
17546   rtx op1 = gen_reg_rtx (XFmode);
17548   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17549   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17551   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17552   DONE;
17556 ;; Block operation instructions
17558 (define_insn "cld"
17559  [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17560  ""
17561  "cld"
17562   [(set_attr "type" "cld")])
17564 (define_expand "movmemsi"
17565   [(use (match_operand:BLK 0 "memory_operand" ""))
17566    (use (match_operand:BLK 1 "memory_operand" ""))
17567    (use (match_operand:SI 2 "nonmemory_operand" ""))
17568    (use (match_operand:SI 3 "const_int_operand" ""))]
17569   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17571  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17572    DONE;
17573  else
17574    FAIL;
17577 (define_expand "movmemdi"
17578   [(use (match_operand:BLK 0 "memory_operand" ""))
17579    (use (match_operand:BLK 1 "memory_operand" ""))
17580    (use (match_operand:DI 2 "nonmemory_operand" ""))
17581    (use (match_operand:DI 3 "const_int_operand" ""))]
17582   "TARGET_64BIT"
17584  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17585    DONE;
17586  else
17587    FAIL;
17590 ;; Most CPUs don't like single string operations
17591 ;; Handle this case here to simplify previous expander.
17593 (define_expand "strmov"
17594   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17595    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17596    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17597               (clobber (reg:CC FLAGS_REG))])
17598    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17599               (clobber (reg:CC FLAGS_REG))])]
17600   ""
17602   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17604   /* If .md ever supports :P for Pmode, these can be directly
17605      in the pattern above.  */
17606   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17607   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17609   if (TARGET_SINGLE_STRINGOP || optimize_size)
17610     {
17611       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17612                                       operands[2], operands[3],
17613                                       operands[5], operands[6]));
17614       DONE;
17615     }
17617   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17620 (define_expand "strmov_singleop"
17621   [(parallel [(set (match_operand 1 "memory_operand" "")
17622                    (match_operand 3 "memory_operand" ""))
17623               (set (match_operand 0 "register_operand" "")
17624                    (match_operand 4 "" ""))
17625               (set (match_operand 2 "register_operand" "")
17626                    (match_operand 5 "" ""))
17627               (use (reg:SI DIRFLAG_REG))])]
17628   "TARGET_SINGLE_STRINGOP || optimize_size"
17629   "")
17631 (define_insn "*strmovdi_rex_1"
17632   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17633         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17634    (set (match_operand:DI 0 "register_operand" "=D")
17635         (plus:DI (match_dup 2)
17636                  (const_int 8)))
17637    (set (match_operand:DI 1 "register_operand" "=S")
17638         (plus:DI (match_dup 3)
17639                  (const_int 8)))
17640    (use (reg:SI DIRFLAG_REG))]
17641   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17642   "movsq"
17643   [(set_attr "type" "str")
17644    (set_attr "mode" "DI")
17645    (set_attr "memory" "both")])
17647 (define_insn "*strmovsi_1"
17648   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17649         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17650    (set (match_operand:SI 0 "register_operand" "=D")
17651         (plus:SI (match_dup 2)
17652                  (const_int 4)))
17653    (set (match_operand:SI 1 "register_operand" "=S")
17654         (plus:SI (match_dup 3)
17655                  (const_int 4)))
17656    (use (reg:SI DIRFLAG_REG))]
17657   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17658   "{movsl|movsd}"
17659   [(set_attr "type" "str")
17660    (set_attr "mode" "SI")
17661    (set_attr "memory" "both")])
17663 (define_insn "*strmovsi_rex_1"
17664   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17665         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17666    (set (match_operand:DI 0 "register_operand" "=D")
17667         (plus:DI (match_dup 2)
17668                  (const_int 4)))
17669    (set (match_operand:DI 1 "register_operand" "=S")
17670         (plus:DI (match_dup 3)
17671                  (const_int 4)))
17672    (use (reg:SI DIRFLAG_REG))]
17673   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17674   "{movsl|movsd}"
17675   [(set_attr "type" "str")
17676    (set_attr "mode" "SI")
17677    (set_attr "memory" "both")])
17679 (define_insn "*strmovhi_1"
17680   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17681         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17682    (set (match_operand:SI 0 "register_operand" "=D")
17683         (plus:SI (match_dup 2)
17684                  (const_int 2)))
17685    (set (match_operand:SI 1 "register_operand" "=S")
17686         (plus:SI (match_dup 3)
17687                  (const_int 2)))
17688    (use (reg:SI DIRFLAG_REG))]
17689   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17690   "movsw"
17691   [(set_attr "type" "str")
17692    (set_attr "memory" "both")
17693    (set_attr "mode" "HI")])
17695 (define_insn "*strmovhi_rex_1"
17696   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17697         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17698    (set (match_operand:DI 0 "register_operand" "=D")
17699         (plus:DI (match_dup 2)
17700                  (const_int 2)))
17701    (set (match_operand:DI 1 "register_operand" "=S")
17702         (plus:DI (match_dup 3)
17703                  (const_int 2)))
17704    (use (reg:SI DIRFLAG_REG))]
17705   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17706   "movsw"
17707   [(set_attr "type" "str")
17708    (set_attr "memory" "both")
17709    (set_attr "mode" "HI")])
17711 (define_insn "*strmovqi_1"
17712   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17713         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17714    (set (match_operand:SI 0 "register_operand" "=D")
17715         (plus:SI (match_dup 2)
17716                  (const_int 1)))
17717    (set (match_operand:SI 1 "register_operand" "=S")
17718         (plus:SI (match_dup 3)
17719                  (const_int 1)))
17720    (use (reg:SI DIRFLAG_REG))]
17721   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17722   "movsb"
17723   [(set_attr "type" "str")
17724    (set_attr "memory" "both")
17725    (set_attr "mode" "QI")])
17727 (define_insn "*strmovqi_rex_1"
17728   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17729         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17730    (set (match_operand:DI 0 "register_operand" "=D")
17731         (plus:DI (match_dup 2)
17732                  (const_int 1)))
17733    (set (match_operand:DI 1 "register_operand" "=S")
17734         (plus:DI (match_dup 3)
17735                  (const_int 1)))
17736    (use (reg:SI DIRFLAG_REG))]
17737   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17738   "movsb"
17739   [(set_attr "type" "str")
17740    (set_attr "memory" "both")
17741    (set_attr "mode" "QI")])
17743 (define_expand "rep_mov"
17744   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17745               (set (match_operand 0 "register_operand" "")
17746                    (match_operand 5 "" ""))
17747               (set (match_operand 2 "register_operand" "")
17748                    (match_operand 6 "" ""))
17749               (set (match_operand 1 "memory_operand" "")
17750                    (match_operand 3 "memory_operand" ""))
17751               (use (match_dup 4))
17752               (use (reg:SI DIRFLAG_REG))])]
17753   ""
17754   "")
17756 (define_insn "*rep_movdi_rex64"
17757   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17758    (set (match_operand:DI 0 "register_operand" "=D") 
17759         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17760                             (const_int 3))
17761                  (match_operand:DI 3 "register_operand" "0")))
17762    (set (match_operand:DI 1 "register_operand" "=S") 
17763         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17764                  (match_operand:DI 4 "register_operand" "1")))
17765    (set (mem:BLK (match_dup 3))
17766         (mem:BLK (match_dup 4)))
17767    (use (match_dup 5))
17768    (use (reg:SI DIRFLAG_REG))]
17769   "TARGET_64BIT"
17770   "{rep\;movsq|rep movsq}"
17771   [(set_attr "type" "str")
17772    (set_attr "prefix_rep" "1")
17773    (set_attr "memory" "both")
17774    (set_attr "mode" "DI")])
17776 (define_insn "*rep_movsi"
17777   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17778    (set (match_operand:SI 0 "register_operand" "=D") 
17779         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17780                             (const_int 2))
17781                  (match_operand:SI 3 "register_operand" "0")))
17782    (set (match_operand:SI 1 "register_operand" "=S") 
17783         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17784                  (match_operand:SI 4 "register_operand" "1")))
17785    (set (mem:BLK (match_dup 3))
17786         (mem:BLK (match_dup 4)))
17787    (use (match_dup 5))
17788    (use (reg:SI DIRFLAG_REG))]
17789   "!TARGET_64BIT"
17790   "{rep\;movsl|rep movsd}"
17791   [(set_attr "type" "str")
17792    (set_attr "prefix_rep" "1")
17793    (set_attr "memory" "both")
17794    (set_attr "mode" "SI")])
17796 (define_insn "*rep_movsi_rex64"
17797   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17798    (set (match_operand:DI 0 "register_operand" "=D") 
17799         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17800                             (const_int 2))
17801                  (match_operand:DI 3 "register_operand" "0")))
17802    (set (match_operand:DI 1 "register_operand" "=S") 
17803         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17804                  (match_operand:DI 4 "register_operand" "1")))
17805    (set (mem:BLK (match_dup 3))
17806         (mem:BLK (match_dup 4)))
17807    (use (match_dup 5))
17808    (use (reg:SI DIRFLAG_REG))]
17809   "TARGET_64BIT"
17810   "{rep\;movsl|rep movsd}"
17811   [(set_attr "type" "str")
17812    (set_attr "prefix_rep" "1")
17813    (set_attr "memory" "both")
17814    (set_attr "mode" "SI")])
17816 (define_insn "*rep_movqi"
17817   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17818    (set (match_operand:SI 0 "register_operand" "=D") 
17819         (plus:SI (match_operand:SI 3 "register_operand" "0")
17820                  (match_operand:SI 5 "register_operand" "2")))
17821    (set (match_operand:SI 1 "register_operand" "=S") 
17822         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17823    (set (mem:BLK (match_dup 3))
17824         (mem:BLK (match_dup 4)))
17825    (use (match_dup 5))
17826    (use (reg:SI DIRFLAG_REG))]
17827   "!TARGET_64BIT"
17828   "{rep\;movsb|rep movsb}"
17829   [(set_attr "type" "str")
17830    (set_attr "prefix_rep" "1")
17831    (set_attr "memory" "both")
17832    (set_attr "mode" "SI")])
17834 (define_insn "*rep_movqi_rex64"
17835   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17836    (set (match_operand:DI 0 "register_operand" "=D") 
17837         (plus:DI (match_operand:DI 3 "register_operand" "0")
17838                  (match_operand:DI 5 "register_operand" "2")))
17839    (set (match_operand:DI 1 "register_operand" "=S") 
17840         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17841    (set (mem:BLK (match_dup 3))
17842         (mem:BLK (match_dup 4)))
17843    (use (match_dup 5))
17844    (use (reg:SI DIRFLAG_REG))]
17845   "TARGET_64BIT"
17846   "{rep\;movsb|rep movsb}"
17847   [(set_attr "type" "str")
17848    (set_attr "prefix_rep" "1")
17849    (set_attr "memory" "both")
17850    (set_attr "mode" "SI")])
17852 (define_expand "setmemsi"
17853    [(use (match_operand:BLK 0 "memory_operand" ""))
17854     (use (match_operand:SI 1 "nonmemory_operand" ""))
17855     (use (match_operand 2 "const_int_operand" ""))
17856     (use (match_operand 3 "const_int_operand" ""))]
17857   ""
17859  /* If value to set is not zero, use the library routine.  */
17860  if (operands[2] != const0_rtx)
17861    FAIL;
17863  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17864    DONE;
17865  else
17866    FAIL;
17869 (define_expand "setmemdi"
17870    [(use (match_operand:BLK 0 "memory_operand" ""))
17871     (use (match_operand:DI 1 "nonmemory_operand" ""))
17872     (use (match_operand 2 "const_int_operand" ""))
17873     (use (match_operand 3 "const_int_operand" ""))]
17874   "TARGET_64BIT"
17876  /* If value to set is not zero, use the library routine.  */
17877  if (operands[2] != const0_rtx)
17878    FAIL;
17880  if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17881    DONE;
17882  else
17883    FAIL;
17886 ;; Most CPUs don't like single string operations
17887 ;; Handle this case here to simplify previous expander.
17889 (define_expand "strset"
17890   [(set (match_operand 1 "memory_operand" "")
17891         (match_operand 2 "register_operand" ""))
17892    (parallel [(set (match_operand 0 "register_operand" "")
17893                    (match_dup 3))
17894               (clobber (reg:CC FLAGS_REG))])]
17895   ""
17897   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17898     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17900   /* If .md ever supports :P for Pmode, this can be directly
17901      in the pattern above.  */
17902   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17903                               GEN_INT (GET_MODE_SIZE (GET_MODE
17904                                                       (operands[2]))));
17905   if (TARGET_SINGLE_STRINGOP || optimize_size)
17906     {
17907       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17908                                       operands[3]));
17909       DONE;
17910     }
17913 (define_expand "strset_singleop"
17914   [(parallel [(set (match_operand 1 "memory_operand" "")
17915                    (match_operand 2 "register_operand" ""))
17916               (set (match_operand 0 "register_operand" "")
17917                    (match_operand 3 "" ""))
17918               (use (reg:SI DIRFLAG_REG))])]
17919   "TARGET_SINGLE_STRINGOP || optimize_size"
17920   "")
17922 (define_insn "*strsetdi_rex_1"
17923   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17924         (match_operand:DI 2 "register_operand" "a"))
17925    (set (match_operand:DI 0 "register_operand" "=D")
17926         (plus:DI (match_dup 1)
17927                  (const_int 8)))
17928    (use (reg:SI DIRFLAG_REG))]
17929   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17930   "stosq"
17931   [(set_attr "type" "str")
17932    (set_attr "memory" "store")
17933    (set_attr "mode" "DI")])
17935 (define_insn "*strsetsi_1"
17936   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17937         (match_operand:SI 2 "register_operand" "a"))
17938    (set (match_operand:SI 0 "register_operand" "=D")
17939         (plus:SI (match_dup 1)
17940                  (const_int 4)))
17941    (use (reg:SI DIRFLAG_REG))]
17942   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17943   "{stosl|stosd}"
17944   [(set_attr "type" "str")
17945    (set_attr "memory" "store")
17946    (set_attr "mode" "SI")])
17948 (define_insn "*strsetsi_rex_1"
17949   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17950         (match_operand:SI 2 "register_operand" "a"))
17951    (set (match_operand:DI 0 "register_operand" "=D")
17952         (plus:DI (match_dup 1)
17953                  (const_int 4)))
17954    (use (reg:SI DIRFLAG_REG))]
17955   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17956   "{stosl|stosd}"
17957   [(set_attr "type" "str")
17958    (set_attr "memory" "store")
17959    (set_attr "mode" "SI")])
17961 (define_insn "*strsethi_1"
17962   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17963         (match_operand:HI 2 "register_operand" "a"))
17964    (set (match_operand:SI 0 "register_operand" "=D")
17965         (plus:SI (match_dup 1)
17966                  (const_int 2)))
17967    (use (reg:SI DIRFLAG_REG))]
17968   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17969   "stosw"
17970   [(set_attr "type" "str")
17971    (set_attr "memory" "store")
17972    (set_attr "mode" "HI")])
17974 (define_insn "*strsethi_rex_1"
17975   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17976         (match_operand:HI 2 "register_operand" "a"))
17977    (set (match_operand:DI 0 "register_operand" "=D")
17978         (plus:DI (match_dup 1)
17979                  (const_int 2)))
17980    (use (reg:SI DIRFLAG_REG))]
17981   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17982   "stosw"
17983   [(set_attr "type" "str")
17984    (set_attr "memory" "store")
17985    (set_attr "mode" "HI")])
17987 (define_insn "*strsetqi_1"
17988   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17989         (match_operand:QI 2 "register_operand" "a"))
17990    (set (match_operand:SI 0 "register_operand" "=D")
17991         (plus:SI (match_dup 1)
17992                  (const_int 1)))
17993    (use (reg:SI DIRFLAG_REG))]
17994   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17995   "stosb"
17996   [(set_attr "type" "str")
17997    (set_attr "memory" "store")
17998    (set_attr "mode" "QI")])
18000 (define_insn "*strsetqi_rex_1"
18001   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18002         (match_operand:QI 2 "register_operand" "a"))
18003    (set (match_operand:DI 0 "register_operand" "=D")
18004         (plus:DI (match_dup 1)
18005                  (const_int 1)))
18006    (use (reg:SI DIRFLAG_REG))]
18007   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18008   "stosb"
18009   [(set_attr "type" "str")
18010    (set_attr "memory" "store")
18011    (set_attr "mode" "QI")])
18013 (define_expand "rep_stos"
18014   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18015               (set (match_operand 0 "register_operand" "")
18016                    (match_operand 4 "" ""))
18017               (set (match_operand 2 "memory_operand" "") (const_int 0))
18018               (use (match_operand 3 "register_operand" ""))
18019               (use (match_dup 1))
18020               (use (reg:SI DIRFLAG_REG))])]
18021   ""
18022   "")
18024 (define_insn "*rep_stosdi_rex64"
18025   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18026    (set (match_operand:DI 0 "register_operand" "=D") 
18027         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18028                             (const_int 3))
18029                  (match_operand:DI 3 "register_operand" "0")))
18030    (set (mem:BLK (match_dup 3))
18031         (const_int 0))
18032    (use (match_operand:DI 2 "register_operand" "a"))
18033    (use (match_dup 4))
18034    (use (reg:SI DIRFLAG_REG))]
18035   "TARGET_64BIT"
18036   "{rep\;stosq|rep stosq}"
18037   [(set_attr "type" "str")
18038    (set_attr "prefix_rep" "1")
18039    (set_attr "memory" "store")
18040    (set_attr "mode" "DI")])
18042 (define_insn "*rep_stossi"
18043   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18044    (set (match_operand:SI 0 "register_operand" "=D") 
18045         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18046                             (const_int 2))
18047                  (match_operand:SI 3 "register_operand" "0")))
18048    (set (mem:BLK (match_dup 3))
18049         (const_int 0))
18050    (use (match_operand:SI 2 "register_operand" "a"))
18051    (use (match_dup 4))
18052    (use (reg:SI DIRFLAG_REG))]
18053   "!TARGET_64BIT"
18054   "{rep\;stosl|rep stosd}"
18055   [(set_attr "type" "str")
18056    (set_attr "prefix_rep" "1")
18057    (set_attr "memory" "store")
18058    (set_attr "mode" "SI")])
18060 (define_insn "*rep_stossi_rex64"
18061   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18062    (set (match_operand:DI 0 "register_operand" "=D") 
18063         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18064                             (const_int 2))
18065                  (match_operand:DI 3 "register_operand" "0")))
18066    (set (mem:BLK (match_dup 3))
18067         (const_int 0))
18068    (use (match_operand:SI 2 "register_operand" "a"))
18069    (use (match_dup 4))
18070    (use (reg:SI DIRFLAG_REG))]
18071   "TARGET_64BIT"
18072   "{rep\;stosl|rep stosd}"
18073   [(set_attr "type" "str")
18074    (set_attr "prefix_rep" "1")
18075    (set_attr "memory" "store")
18076    (set_attr "mode" "SI")])
18078 (define_insn "*rep_stosqi"
18079   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18080    (set (match_operand:SI 0 "register_operand" "=D") 
18081         (plus:SI (match_operand:SI 3 "register_operand" "0")
18082                  (match_operand:SI 4 "register_operand" "1")))
18083    (set (mem:BLK (match_dup 3))
18084         (const_int 0))
18085    (use (match_operand:QI 2 "register_operand" "a"))
18086    (use (match_dup 4))
18087    (use (reg:SI DIRFLAG_REG))]
18088   "!TARGET_64BIT"
18089   "{rep\;stosb|rep stosb}"
18090   [(set_attr "type" "str")
18091    (set_attr "prefix_rep" "1")
18092    (set_attr "memory" "store")
18093    (set_attr "mode" "QI")])
18095 (define_insn "*rep_stosqi_rex64"
18096   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18097    (set (match_operand:DI 0 "register_operand" "=D") 
18098         (plus:DI (match_operand:DI 3 "register_operand" "0")
18099                  (match_operand:DI 4 "register_operand" "1")))
18100    (set (mem:BLK (match_dup 3))
18101         (const_int 0))
18102    (use (match_operand:QI 2 "register_operand" "a"))
18103    (use (match_dup 4))
18104    (use (reg:SI DIRFLAG_REG))]
18105   "TARGET_64BIT"
18106   "{rep\;stosb|rep stosb}"
18107   [(set_attr "type" "str")
18108    (set_attr "prefix_rep" "1")
18109    (set_attr "memory" "store")
18110    (set_attr "mode" "QI")])
18112 (define_expand "cmpstrnsi"
18113   [(set (match_operand:SI 0 "register_operand" "")
18114         (compare:SI (match_operand:BLK 1 "general_operand" "")
18115                     (match_operand:BLK 2 "general_operand" "")))
18116    (use (match_operand 3 "general_operand" ""))
18117    (use (match_operand 4 "immediate_operand" ""))]
18118   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18120   rtx addr1, addr2, out, outlow, count, countreg, align;
18122   /* Can't use this if the user has appropriated esi or edi.  */
18123   if (global_regs[4] || global_regs[5])
18124     FAIL;
18126   out = operands[0];
18127   if (GET_CODE (out) != REG)
18128     out = gen_reg_rtx (SImode);
18130   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18131   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18132   if (addr1 != XEXP (operands[1], 0))
18133     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18134   if (addr2 != XEXP (operands[2], 0))
18135     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18137   count = operands[3];
18138   countreg = ix86_zero_extend_to_Pmode (count);
18140   /* %%% Iff we are testing strict equality, we can use known alignment
18141      to good advantage.  This may be possible with combine, particularly
18142      once cc0 is dead.  */
18143   align = operands[4];
18145   emit_insn (gen_cld ());
18146   if (GET_CODE (count) == CONST_INT)
18147     {
18148       if (INTVAL (count) == 0)
18149         {
18150           emit_move_insn (operands[0], const0_rtx);
18151           DONE;
18152         }
18153       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18154                                      operands[1], operands[2]));
18155     }
18156   else
18157     {
18158       if (TARGET_64BIT)
18159         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18160       else
18161         emit_insn (gen_cmpsi_1 (countreg, countreg));
18162       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18163                                   operands[1], operands[2]));
18164     }
18166   outlow = gen_lowpart (QImode, out);
18167   emit_insn (gen_cmpintqi (outlow));
18168   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18170   if (operands[0] != out)
18171     emit_move_insn (operands[0], out);
18173   DONE;
18176 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18178 (define_expand "cmpintqi"
18179   [(set (match_dup 1)
18180         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18181    (set (match_dup 2)
18182         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18183    (parallel [(set (match_operand:QI 0 "register_operand" "")
18184                    (minus:QI (match_dup 1)
18185                              (match_dup 2)))
18186               (clobber (reg:CC FLAGS_REG))])]
18187   ""
18188   "operands[1] = gen_reg_rtx (QImode);
18189    operands[2] = gen_reg_rtx (QImode);")
18191 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18192 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18194 (define_expand "cmpstrnqi_nz_1"
18195   [(parallel [(set (reg:CC FLAGS_REG)
18196                    (compare:CC (match_operand 4 "memory_operand" "")
18197                                (match_operand 5 "memory_operand" "")))
18198               (use (match_operand 2 "register_operand" ""))
18199               (use (match_operand:SI 3 "immediate_operand" ""))
18200               (use (reg:SI DIRFLAG_REG))
18201               (clobber (match_operand 0 "register_operand" ""))
18202               (clobber (match_operand 1 "register_operand" ""))
18203               (clobber (match_dup 2))])]
18204   ""
18205   "")
18207 (define_insn "*cmpstrnqi_nz_1"
18208   [(set (reg:CC FLAGS_REG)
18209         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18210                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18211    (use (match_operand:SI 6 "register_operand" "2"))
18212    (use (match_operand:SI 3 "immediate_operand" "i"))
18213    (use (reg:SI DIRFLAG_REG))
18214    (clobber (match_operand:SI 0 "register_operand" "=S"))
18215    (clobber (match_operand:SI 1 "register_operand" "=D"))
18216    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18217   "!TARGET_64BIT"
18218   "repz{\;| }cmpsb"
18219   [(set_attr "type" "str")
18220    (set_attr "mode" "QI")
18221    (set_attr "prefix_rep" "1")])
18223 (define_insn "*cmpstrnqi_nz_rex_1"
18224   [(set (reg:CC FLAGS_REG)
18225         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18226                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18227    (use (match_operand:DI 6 "register_operand" "2"))
18228    (use (match_operand:SI 3 "immediate_operand" "i"))
18229    (use (reg:SI DIRFLAG_REG))
18230    (clobber (match_operand:DI 0 "register_operand" "=S"))
18231    (clobber (match_operand:DI 1 "register_operand" "=D"))
18232    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18233   "TARGET_64BIT"
18234   "repz{\;| }cmpsb"
18235   [(set_attr "type" "str")
18236    (set_attr "mode" "QI")
18237    (set_attr "prefix_rep" "1")])
18239 ;; The same, but the count is not known to not be zero.
18241 (define_expand "cmpstrnqi_1"
18242   [(parallel [(set (reg:CC FLAGS_REG)
18243                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18244                                      (const_int 0))
18245                   (compare:CC (match_operand 4 "memory_operand" "")
18246                               (match_operand 5 "memory_operand" ""))
18247                   (const_int 0)))
18248               (use (match_operand:SI 3 "immediate_operand" ""))
18249               (use (reg:CC FLAGS_REG))
18250               (use (reg:SI DIRFLAG_REG))
18251               (clobber (match_operand 0 "register_operand" ""))
18252               (clobber (match_operand 1 "register_operand" ""))
18253               (clobber (match_dup 2))])]
18254   ""
18255   "")
18257 (define_insn "*cmpstrnqi_1"
18258   [(set (reg:CC FLAGS_REG)
18259         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18260                              (const_int 0))
18261           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18262                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18263           (const_int 0)))
18264    (use (match_operand:SI 3 "immediate_operand" "i"))
18265    (use (reg:CC FLAGS_REG))
18266    (use (reg:SI DIRFLAG_REG))
18267    (clobber (match_operand:SI 0 "register_operand" "=S"))
18268    (clobber (match_operand:SI 1 "register_operand" "=D"))
18269    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18270   "!TARGET_64BIT"
18271   "repz{\;| }cmpsb"
18272   [(set_attr "type" "str")
18273    (set_attr "mode" "QI")
18274    (set_attr "prefix_rep" "1")])
18276 (define_insn "*cmpstrnqi_rex_1"
18277   [(set (reg:CC FLAGS_REG)
18278         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18279                              (const_int 0))
18280           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18281                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18282           (const_int 0)))
18283    (use (match_operand:SI 3 "immediate_operand" "i"))
18284    (use (reg:CC FLAGS_REG))
18285    (use (reg:SI DIRFLAG_REG))
18286    (clobber (match_operand:DI 0 "register_operand" "=S"))
18287    (clobber (match_operand:DI 1 "register_operand" "=D"))
18288    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18289   "TARGET_64BIT"
18290   "repz{\;| }cmpsb"
18291   [(set_attr "type" "str")
18292    (set_attr "mode" "QI")
18293    (set_attr "prefix_rep" "1")])
18295 (define_expand "strlensi"
18296   [(set (match_operand:SI 0 "register_operand" "")
18297         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18298                     (match_operand:QI 2 "immediate_operand" "")
18299                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18300   ""
18302  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18303    DONE;
18304  else
18305    FAIL;
18308 (define_expand "strlendi"
18309   [(set (match_operand:DI 0 "register_operand" "")
18310         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18311                     (match_operand:QI 2 "immediate_operand" "")
18312                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18313   ""
18315  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18316    DONE;
18317  else
18318    FAIL;
18321 (define_expand "strlenqi_1"
18322   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18323               (use (reg:SI DIRFLAG_REG))
18324               (clobber (match_operand 1 "register_operand" ""))
18325               (clobber (reg:CC FLAGS_REG))])]
18326   ""
18327   "")
18329 (define_insn "*strlenqi_1"
18330   [(set (match_operand:SI 0 "register_operand" "=&c")
18331         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18332                     (match_operand:QI 2 "register_operand" "a")
18333                     (match_operand:SI 3 "immediate_operand" "i")
18334                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18335    (use (reg:SI DIRFLAG_REG))
18336    (clobber (match_operand:SI 1 "register_operand" "=D"))
18337    (clobber (reg:CC FLAGS_REG))]
18338   "!TARGET_64BIT"
18339   "repnz{\;| }scasb"
18340   [(set_attr "type" "str")
18341    (set_attr "mode" "QI")
18342    (set_attr "prefix_rep" "1")])
18344 (define_insn "*strlenqi_rex_1"
18345   [(set (match_operand:DI 0 "register_operand" "=&c")
18346         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18347                     (match_operand:QI 2 "register_operand" "a")
18348                     (match_operand:DI 3 "immediate_operand" "i")
18349                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18350    (use (reg:SI DIRFLAG_REG))
18351    (clobber (match_operand:DI 1 "register_operand" "=D"))
18352    (clobber (reg:CC FLAGS_REG))]
18353   "TARGET_64BIT"
18354   "repnz{\;| }scasb"
18355   [(set_attr "type" "str")
18356    (set_attr "mode" "QI")
18357    (set_attr "prefix_rep" "1")])
18359 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18360 ;; handled in combine, but it is not currently up to the task.
18361 ;; When used for their truth value, the cmpstrn* expanders generate
18362 ;; code like this:
18364 ;;   repz cmpsb
18365 ;;   seta       %al
18366 ;;   setb       %dl
18367 ;;   cmpb       %al, %dl
18368 ;;   jcc        label
18370 ;; The intermediate three instructions are unnecessary.
18372 ;; This one handles cmpstrn*_nz_1...
18373 (define_peephole2
18374   [(parallel[
18375      (set (reg:CC FLAGS_REG)
18376           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18377                       (mem:BLK (match_operand 5 "register_operand" ""))))
18378      (use (match_operand 6 "register_operand" ""))
18379      (use (match_operand:SI 3 "immediate_operand" ""))
18380      (use (reg:SI DIRFLAG_REG))
18381      (clobber (match_operand 0 "register_operand" ""))
18382      (clobber (match_operand 1 "register_operand" ""))
18383      (clobber (match_operand 2 "register_operand" ""))])
18384    (set (match_operand:QI 7 "register_operand" "")
18385         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18386    (set (match_operand:QI 8 "register_operand" "")
18387         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18388    (set (reg FLAGS_REG)
18389         (compare (match_dup 7) (match_dup 8)))
18390   ]
18391   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18392   [(parallel[
18393      (set (reg:CC FLAGS_REG)
18394           (compare:CC (mem:BLK (match_dup 4))
18395                       (mem:BLK (match_dup 5))))
18396      (use (match_dup 6))
18397      (use (match_dup 3))
18398      (use (reg:SI DIRFLAG_REG))
18399      (clobber (match_dup 0))
18400      (clobber (match_dup 1))
18401      (clobber (match_dup 2))])]
18402   "")
18404 ;; ...and this one handles cmpstrn*_1.
18405 (define_peephole2
18406   [(parallel[
18407      (set (reg:CC FLAGS_REG)
18408           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18409                                (const_int 0))
18410             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18411                         (mem:BLK (match_operand 5 "register_operand" "")))
18412             (const_int 0)))
18413      (use (match_operand:SI 3 "immediate_operand" ""))
18414      (use (reg:CC FLAGS_REG))
18415      (use (reg:SI DIRFLAG_REG))
18416      (clobber (match_operand 0 "register_operand" ""))
18417      (clobber (match_operand 1 "register_operand" ""))
18418      (clobber (match_operand 2 "register_operand" ""))])
18419    (set (match_operand:QI 7 "register_operand" "")
18420         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18421    (set (match_operand:QI 8 "register_operand" "")
18422         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18423    (set (reg FLAGS_REG)
18424         (compare (match_dup 7) (match_dup 8)))
18425   ]
18426   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18427   [(parallel[
18428      (set (reg:CC FLAGS_REG)
18429           (if_then_else:CC (ne (match_dup 6)
18430                                (const_int 0))
18431             (compare:CC (mem:BLK (match_dup 4))
18432                         (mem:BLK (match_dup 5)))
18433             (const_int 0)))
18434      (use (match_dup 3))
18435      (use (reg:CC FLAGS_REG))
18436      (use (reg:SI DIRFLAG_REG))
18437      (clobber (match_dup 0))
18438      (clobber (match_dup 1))
18439      (clobber (match_dup 2))])]
18440   "")
18444 ;; Conditional move instructions.
18446 (define_expand "movdicc"
18447   [(set (match_operand:DI 0 "register_operand" "")
18448         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18449                          (match_operand:DI 2 "general_operand" "")
18450                          (match_operand:DI 3 "general_operand" "")))]
18451   "TARGET_64BIT"
18452   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18454 (define_insn "x86_movdicc_0_m1_rex64"
18455   [(set (match_operand:DI 0 "register_operand" "=r")
18456         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18457           (const_int -1)
18458           (const_int 0)))
18459    (clobber (reg:CC FLAGS_REG))]
18460   "TARGET_64BIT"
18461   "sbb{q}\t%0, %0"
18462   ; Since we don't have the proper number of operands for an alu insn,
18463   ; fill in all the blanks.
18464   [(set_attr "type" "alu")
18465    (set_attr "pent_pair" "pu")
18466    (set_attr "memory" "none")
18467    (set_attr "imm_disp" "false")
18468    (set_attr "mode" "DI")
18469    (set_attr "length_immediate" "0")])
18471 (define_insn "*movdicc_c_rex64"
18472   [(set (match_operand:DI 0 "register_operand" "=r,r")
18473         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18474                                 [(reg FLAGS_REG) (const_int 0)])
18475                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18476                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18477   "TARGET_64BIT && TARGET_CMOVE
18478    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18479   "@
18480    cmov%O2%C1\t{%2, %0|%0, %2}
18481    cmov%O2%c1\t{%3, %0|%0, %3}"
18482   [(set_attr "type" "icmov")
18483    (set_attr "mode" "DI")])
18485 (define_expand "movsicc"
18486   [(set (match_operand:SI 0 "register_operand" "")
18487         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18488                          (match_operand:SI 2 "general_operand" "")
18489                          (match_operand:SI 3 "general_operand" "")))]
18490   ""
18491   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18493 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18494 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18495 ;; So just document what we're doing explicitly.
18497 (define_insn "x86_movsicc_0_m1"
18498   [(set (match_operand:SI 0 "register_operand" "=r")
18499         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18500           (const_int -1)
18501           (const_int 0)))
18502    (clobber (reg:CC FLAGS_REG))]
18503   ""
18504   "sbb{l}\t%0, %0"
18505   ; Since we don't have the proper number of operands for an alu insn,
18506   ; fill in all the blanks.
18507   [(set_attr "type" "alu")
18508    (set_attr "pent_pair" "pu")
18509    (set_attr "memory" "none")
18510    (set_attr "imm_disp" "false")
18511    (set_attr "mode" "SI")
18512    (set_attr "length_immediate" "0")])
18514 (define_insn "*movsicc_noc"
18515   [(set (match_operand:SI 0 "register_operand" "=r,r")
18516         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18517                                 [(reg FLAGS_REG) (const_int 0)])
18518                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18519                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18520   "TARGET_CMOVE
18521    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18522   "@
18523    cmov%O2%C1\t{%2, %0|%0, %2}
18524    cmov%O2%c1\t{%3, %0|%0, %3}"
18525   [(set_attr "type" "icmov")
18526    (set_attr "mode" "SI")])
18528 (define_expand "movhicc"
18529   [(set (match_operand:HI 0 "register_operand" "")
18530         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18531                          (match_operand:HI 2 "general_operand" "")
18532                          (match_operand:HI 3 "general_operand" "")))]
18533   "TARGET_HIMODE_MATH"
18534   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18536 (define_insn "*movhicc_noc"
18537   [(set (match_operand:HI 0 "register_operand" "=r,r")
18538         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18539                                 [(reg FLAGS_REG) (const_int 0)])
18540                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18541                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18542   "TARGET_CMOVE
18543    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18544   "@
18545    cmov%O2%C1\t{%2, %0|%0, %2}
18546    cmov%O2%c1\t{%3, %0|%0, %3}"
18547   [(set_attr "type" "icmov")
18548    (set_attr "mode" "HI")])
18550 (define_expand "movqicc"
18551   [(set (match_operand:QI 0 "register_operand" "")
18552         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18553                          (match_operand:QI 2 "general_operand" "")
18554                          (match_operand:QI 3 "general_operand" "")))]
18555   "TARGET_QIMODE_MATH"
18556   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18558 (define_insn_and_split "*movqicc_noc"
18559   [(set (match_operand:QI 0 "register_operand" "=r,r")
18560         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18561                                 [(match_operand 4 "flags_reg_operand" "")
18562                                  (const_int 0)])
18563                       (match_operand:QI 2 "register_operand" "r,0")
18564                       (match_operand:QI 3 "register_operand" "0,r")))]
18565   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18566   "#"
18567   "&& reload_completed"
18568   [(set (match_dup 0)
18569         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18570                       (match_dup 2)
18571                       (match_dup 3)))]
18572   "operands[0] = gen_lowpart (SImode, operands[0]);
18573    operands[2] = gen_lowpart (SImode, operands[2]);
18574    operands[3] = gen_lowpart (SImode, operands[3]);"
18575   [(set_attr "type" "icmov")
18576    (set_attr "mode" "SI")])
18578 (define_expand "movsfcc"
18579   [(set (match_operand:SF 0 "register_operand" "")
18580         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18581                          (match_operand:SF 2 "register_operand" "")
18582                          (match_operand:SF 3 "register_operand" "")))]
18583   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18584   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18586 (define_insn "*movsfcc_1_387"
18587   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18588         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
18589                                 [(reg FLAGS_REG) (const_int 0)])
18590                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18591                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18592   "TARGET_80387 && TARGET_CMOVE
18593    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18594   "@
18595    fcmov%F1\t{%2, %0|%0, %2}
18596    fcmov%f1\t{%3, %0|%0, %3}
18597    cmov%O2%C1\t{%2, %0|%0, %2}
18598    cmov%O2%c1\t{%3, %0|%0, %3}"
18599   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18600    (set_attr "mode" "SF,SF,SI,SI")])
18602 (define_expand "movdfcc"
18603   [(set (match_operand:DF 0 "register_operand" "")
18604         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18605                          (match_operand:DF 2 "register_operand" "")
18606                          (match_operand:DF 3 "register_operand" "")))]
18607   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18608   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18610 (define_insn "*movdfcc_1"
18611   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18612         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18613                                 [(reg FLAGS_REG) (const_int 0)])
18614                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18615                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18616   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18617    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18618   "@
18619    fcmov%F1\t{%2, %0|%0, %2}
18620    fcmov%f1\t{%3, %0|%0, %3}
18621    #
18622    #"
18623   [(set_attr "type" "fcmov,fcmov,multi,multi")
18624    (set_attr "mode" "DF")])
18626 (define_insn "*movdfcc_1_rex64"
18627   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18628         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18629                                 [(reg FLAGS_REG) (const_int 0)])
18630                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18631                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18632   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18633    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18634   "@
18635    fcmov%F1\t{%2, %0|%0, %2}
18636    fcmov%f1\t{%3, %0|%0, %3}
18637    cmov%O2%C1\t{%2, %0|%0, %2}
18638    cmov%O2%c1\t{%3, %0|%0, %3}"
18639   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18640    (set_attr "mode" "DF")])
18642 (define_split
18643   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18644         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
18645                                 [(match_operand 4 "flags_reg_operand" "")
18646                                  (const_int 0)])
18647                       (match_operand:DF 2 "nonimmediate_operand" "")
18648                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18649   "!TARGET_64BIT && reload_completed"
18650   [(set (match_dup 2)
18651         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18652                       (match_dup 5)
18653                       (match_dup 7)))
18654    (set (match_dup 3)
18655         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18656                       (match_dup 6)
18657                       (match_dup 8)))]
18658   "split_di (operands+2, 1, operands+5, operands+6);
18659    split_di (operands+3, 1, operands+7, operands+8);
18660    split_di (operands, 1, operands+2, operands+3);")
18662 (define_expand "movxfcc"
18663   [(set (match_operand:XF 0 "register_operand" "")
18664         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18665                          (match_operand:XF 2 "register_operand" "")
18666                          (match_operand:XF 3 "register_operand" "")))]
18667   "TARGET_80387 && TARGET_CMOVE"
18668   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18670 (define_insn "*movxfcc_1"
18671   [(set (match_operand:XF 0 "register_operand" "=f,f")
18672         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
18673                                 [(reg FLAGS_REG) (const_int 0)])
18674                       (match_operand:XF 2 "register_operand" "f,0")
18675                       (match_operand:XF 3 "register_operand" "0,f")))]
18676   "TARGET_80387 && TARGET_CMOVE"
18677   "@
18678    fcmov%F1\t{%2, %0|%0, %2}
18679    fcmov%f1\t{%3, %0|%0, %3}"
18680   [(set_attr "type" "fcmov")
18681    (set_attr "mode" "XF")])
18683 ;; These versions of the min/max patterns are intentionally ignorant of
18684 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18685 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18686 ;; are undefined in this condition, we're certain this is correct.
18688 (define_insn "sminsf3"
18689   [(set (match_operand:SF 0 "register_operand" "=x")
18690         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18691                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18692   "TARGET_SSE_MATH"
18693   "minss\t{%2, %0|%0, %2}"
18694   [(set_attr "type" "sseadd")
18695    (set_attr "mode" "SF")])
18697 (define_insn "smaxsf3"
18698   [(set (match_operand:SF 0 "register_operand" "=x")
18699         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18700                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18701   "TARGET_SSE_MATH"
18702   "maxss\t{%2, %0|%0, %2}"
18703   [(set_attr "type" "sseadd")
18704    (set_attr "mode" "SF")])
18706 (define_insn "smindf3"
18707   [(set (match_operand:DF 0 "register_operand" "=x")
18708         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18709                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18710   "TARGET_SSE2 && TARGET_SSE_MATH"
18711   "minsd\t{%2, %0|%0, %2}"
18712   [(set_attr "type" "sseadd")
18713    (set_attr "mode" "DF")])
18715 (define_insn "smaxdf3"
18716   [(set (match_operand:DF 0 "register_operand" "=x")
18717         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18718                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18719   "TARGET_SSE2 && TARGET_SSE_MATH"
18720   "maxsd\t{%2, %0|%0, %2}"
18721   [(set_attr "type" "sseadd")
18722    (set_attr "mode" "DF")])
18724 ;; These versions of the min/max patterns implement exactly the operations
18725 ;;   min = (op1 < op2 ? op1 : op2)
18726 ;;   max = (!(op1 < op2) ? op1 : op2)
18727 ;; Their operands are not commutative, and thus they may be used in the
18728 ;; presence of -0.0 and NaN.
18730 (define_insn "*ieee_sminsf3"
18731   [(set (match_operand:SF 0 "register_operand" "=x")
18732         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18733                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18734                    UNSPEC_IEEE_MIN))]
18735   "TARGET_SSE_MATH"
18736   "minss\t{%2, %0|%0, %2}"
18737   [(set_attr "type" "sseadd")
18738    (set_attr "mode" "SF")])
18740 (define_insn "*ieee_smaxsf3"
18741   [(set (match_operand:SF 0 "register_operand" "=x")
18742         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18743                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18744                    UNSPEC_IEEE_MAX))]
18745   "TARGET_SSE_MATH"
18746   "maxss\t{%2, %0|%0, %2}"
18747   [(set_attr "type" "sseadd")
18748    (set_attr "mode" "SF")])
18750 (define_insn "*ieee_smindf3"
18751   [(set (match_operand:DF 0 "register_operand" "=x")
18752         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18753                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18754                    UNSPEC_IEEE_MIN))]
18755   "TARGET_SSE2 && TARGET_SSE_MATH"
18756   "minsd\t{%2, %0|%0, %2}"
18757   [(set_attr "type" "sseadd")
18758    (set_attr "mode" "DF")])
18760 (define_insn "*ieee_smaxdf3"
18761   [(set (match_operand:DF 0 "register_operand" "=x")
18762         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18763                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18764                    UNSPEC_IEEE_MAX))]
18765   "TARGET_SSE2 && TARGET_SSE_MATH"
18766   "maxsd\t{%2, %0|%0, %2}"
18767   [(set_attr "type" "sseadd")
18768    (set_attr "mode" "DF")])
18770 ;; Conditional addition patterns
18771 (define_expand "addqicc"
18772   [(match_operand:QI 0 "register_operand" "")
18773    (match_operand 1 "comparison_operator" "")
18774    (match_operand:QI 2 "register_operand" "")
18775    (match_operand:QI 3 "const_int_operand" "")]
18776   ""
18777   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18779 (define_expand "addhicc"
18780   [(match_operand:HI 0 "register_operand" "")
18781    (match_operand 1 "comparison_operator" "")
18782    (match_operand:HI 2 "register_operand" "")
18783    (match_operand:HI 3 "const_int_operand" "")]
18784   ""
18785   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18787 (define_expand "addsicc"
18788   [(match_operand:SI 0 "register_operand" "")
18789    (match_operand 1 "comparison_operator" "")
18790    (match_operand:SI 2 "register_operand" "")
18791    (match_operand:SI 3 "const_int_operand" "")]
18792   ""
18793   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18795 (define_expand "adddicc"
18796   [(match_operand:DI 0 "register_operand" "")
18797    (match_operand 1 "comparison_operator" "")
18798    (match_operand:DI 2 "register_operand" "")
18799    (match_operand:DI 3 "const_int_operand" "")]
18800   "TARGET_64BIT"
18801   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18804 ;; Misc patterns (?)
18806 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18807 ;; Otherwise there will be nothing to keep
18808 ;; 
18809 ;; [(set (reg ebp) (reg esp))]
18810 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18811 ;;  (clobber (eflags)]
18812 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18814 ;; in proper program order.
18815 (define_insn "pro_epilogue_adjust_stack_1"
18816   [(set (match_operand:SI 0 "register_operand" "=r,r")
18817         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18818                  (match_operand:SI 2 "immediate_operand" "i,i")))
18819    (clobber (reg:CC FLAGS_REG))
18820    (clobber (mem:BLK (scratch)))]
18821   "!TARGET_64BIT"
18823   switch (get_attr_type (insn))
18824     {
18825     case TYPE_IMOV:
18826       return "mov{l}\t{%1, %0|%0, %1}";
18828     case TYPE_ALU:
18829       if (GET_CODE (operands[2]) == CONST_INT
18830           && (INTVAL (operands[2]) == 128
18831               || (INTVAL (operands[2]) < 0
18832                   && INTVAL (operands[2]) != -128)))
18833         {
18834           operands[2] = GEN_INT (-INTVAL (operands[2]));
18835           return "sub{l}\t{%2, %0|%0, %2}";
18836         }
18837       return "add{l}\t{%2, %0|%0, %2}";
18839     case TYPE_LEA:
18840       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18841       return "lea{l}\t{%a2, %0|%0, %a2}";
18843     default:
18844       gcc_unreachable ();
18845     }
18847   [(set (attr "type")
18848         (cond [(eq_attr "alternative" "0")
18849                  (const_string "alu")
18850                (match_operand:SI 2 "const0_operand" "")
18851                  (const_string "imov")
18852               ]
18853               (const_string "lea")))
18854    (set_attr "mode" "SI")])
18856 (define_insn "pro_epilogue_adjust_stack_rex64"
18857   [(set (match_operand:DI 0 "register_operand" "=r,r")
18858         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18859                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18860    (clobber (reg:CC FLAGS_REG))
18861    (clobber (mem:BLK (scratch)))]
18862   "TARGET_64BIT"
18864   switch (get_attr_type (insn))
18865     {
18866     case TYPE_IMOV:
18867       return "mov{q}\t{%1, %0|%0, %1}";
18869     case TYPE_ALU:
18870       if (GET_CODE (operands[2]) == CONST_INT
18871           /* Avoid overflows.  */
18872           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18873           && (INTVAL (operands[2]) == 128
18874               || (INTVAL (operands[2]) < 0
18875                   && INTVAL (operands[2]) != -128)))
18876         {
18877           operands[2] = GEN_INT (-INTVAL (operands[2]));
18878           return "sub{q}\t{%2, %0|%0, %2}";
18879         }
18880       return "add{q}\t{%2, %0|%0, %2}";
18882     case TYPE_LEA:
18883       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18884       return "lea{q}\t{%a2, %0|%0, %a2}";
18886     default:
18887       gcc_unreachable ();
18888     }
18890   [(set (attr "type")
18891         (cond [(eq_attr "alternative" "0")
18892                  (const_string "alu")
18893                (match_operand:DI 2 "const0_operand" "")
18894                  (const_string "imov")
18895               ]
18896               (const_string "lea")))
18897    (set_attr "mode" "DI")])
18899 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18900   [(set (match_operand:DI 0 "register_operand" "=r,r")
18901         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18902                  (match_operand:DI 3 "immediate_operand" "i,i")))
18903    (use (match_operand:DI 2 "register_operand" "r,r"))
18904    (clobber (reg:CC FLAGS_REG))
18905    (clobber (mem:BLK (scratch)))]
18906   "TARGET_64BIT"
18908   switch (get_attr_type (insn))
18909     {
18910     case TYPE_ALU:
18911       return "add{q}\t{%2, %0|%0, %2}";
18913     case TYPE_LEA:
18914       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18915       return "lea{q}\t{%a2, %0|%0, %a2}";
18917     default:
18918       gcc_unreachable ();
18919     }
18921   [(set_attr "type" "alu,lea")
18922    (set_attr "mode" "DI")])
18924 (define_expand "allocate_stack_worker"
18925   [(match_operand:SI 0 "register_operand" "")]
18926   "TARGET_STACK_PROBE"
18928   if (reload_completed)
18929     {
18930       if (TARGET_64BIT)
18931         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18932       else
18933         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18934     }
18935   else
18936     {
18937       if (TARGET_64BIT)
18938         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18939       else
18940         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18941     }
18942   DONE;
18945 (define_insn "allocate_stack_worker_1"
18946   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18947     UNSPECV_STACK_PROBE)
18948    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18949    (clobber (match_scratch:SI 1 "=0"))
18950    (clobber (reg:CC FLAGS_REG))]
18951   "!TARGET_64BIT && TARGET_STACK_PROBE"
18952   "call\t__alloca"
18953   [(set_attr "type" "multi")
18954    (set_attr "length" "5")])
18956 (define_expand "allocate_stack_worker_postreload"
18957   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18958                                     UNSPECV_STACK_PROBE)
18959               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18960               (clobber (match_dup 0))
18961               (clobber (reg:CC FLAGS_REG))])]
18962   ""
18963   "")
18965 (define_insn "allocate_stack_worker_rex64"
18966   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18967     UNSPECV_STACK_PROBE)
18968    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18969    (clobber (match_scratch:DI 1 "=0"))
18970    (clobber (reg:CC FLAGS_REG))]
18971   "TARGET_64BIT && TARGET_STACK_PROBE"
18972   "call\t__alloca"
18973   [(set_attr "type" "multi")
18974    (set_attr "length" "5")])
18976 (define_expand "allocate_stack_worker_rex64_postreload"
18977   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18978                                     UNSPECV_STACK_PROBE)
18979               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18980               (clobber (match_dup 0))
18981               (clobber (reg:CC FLAGS_REG))])]
18982   ""
18983   "")
18985 (define_expand "allocate_stack"
18986   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18987                    (minus:SI (reg:SI SP_REG)
18988                              (match_operand:SI 1 "general_operand" "")))
18989               (clobber (reg:CC FLAGS_REG))])
18990    (parallel [(set (reg:SI SP_REG)
18991                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
18992               (clobber (reg:CC FLAGS_REG))])]
18993   "TARGET_STACK_PROBE"
18995 #ifdef CHECK_STACK_LIMIT
18996   if (GET_CODE (operands[1]) == CONST_INT
18997       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18998     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18999                            operands[1]));
19000   else 
19001 #endif
19002     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19003                                                             operands[1])));
19005   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19006   DONE;
19009 (define_expand "builtin_setjmp_receiver"
19010   [(label_ref (match_operand 0 "" ""))]
19011   "!TARGET_64BIT && flag_pic"
19013   if (TARGET_MACHO)
19014     {
19015       rtx xops[3];
19016       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19017       rtx label_rtx = gen_label_rtx ();
19018       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19019       xops[0] = xops[1] = picreg;
19020       xops[2] = gen_rtx_CONST (SImode,
19021                   gen_rtx_MINUS (SImode,
19022                     gen_rtx_LABEL_REF (SImode, label_rtx),
19023                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19024       ix86_expand_binary_operator (MINUS, SImode, xops);
19025     }
19026   else
19027     emit_insn (gen_set_got (pic_offset_table_rtx));
19028   DONE;
19031 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19033 (define_split
19034   [(set (match_operand 0 "register_operand" "")
19035         (match_operator 3 "promotable_binary_operator"
19036            [(match_operand 1 "register_operand" "")
19037             (match_operand 2 "aligned_operand" "")]))
19038    (clobber (reg:CC FLAGS_REG))]
19039   "! TARGET_PARTIAL_REG_STALL && reload_completed
19040    && ((GET_MODE (operands[0]) == HImode 
19041         && ((!optimize_size && !TARGET_FAST_PREFIX)
19042             /* ??? next two lines just !satisfies_constraint_K (...) */
19043             || GET_CODE (operands[2]) != CONST_INT
19044             || satisfies_constraint_K (operands[2])))
19045        || (GET_MODE (operands[0]) == QImode 
19046            && (TARGET_PROMOTE_QImode || optimize_size)))"
19047   [(parallel [(set (match_dup 0)
19048                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19049               (clobber (reg:CC FLAGS_REG))])]
19050   "operands[0] = gen_lowpart (SImode, operands[0]);
19051    operands[1] = gen_lowpart (SImode, operands[1]);
19052    if (GET_CODE (operands[3]) != ASHIFT)
19053      operands[2] = gen_lowpart (SImode, operands[2]);
19054    PUT_MODE (operands[3], SImode);")
19056 ; Promote the QImode tests, as i386 has encoding of the AND
19057 ; instruction with 32-bit sign-extended immediate and thus the
19058 ; instruction size is unchanged, except in the %eax case for
19059 ; which it is increased by one byte, hence the ! optimize_size.
19060 (define_split
19061   [(set (match_operand 0 "flags_reg_operand" "")
19062         (match_operator 2 "compare_operator"
19063           [(and (match_operand 3 "aligned_operand" "")
19064                 (match_operand 4 "const_int_operand" ""))
19065            (const_int 0)]))
19066    (set (match_operand 1 "register_operand" "")
19067         (and (match_dup 3) (match_dup 4)))]
19068   "! TARGET_PARTIAL_REG_STALL && reload_completed
19069    /* Ensure that the operand will remain sign-extended immediate.  */
19070    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19071    && ! optimize_size
19072    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19073        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19074   [(parallel [(set (match_dup 0)
19075                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19076                                     (const_int 0)]))
19077               (set (match_dup 1)
19078                    (and:SI (match_dup 3) (match_dup 4)))])]
19080   operands[4]
19081     = gen_int_mode (INTVAL (operands[4])
19082                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19083   operands[1] = gen_lowpart (SImode, operands[1]);
19084   operands[3] = gen_lowpart (SImode, operands[3]);
19087 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19088 ; the TEST instruction with 32-bit sign-extended immediate and thus
19089 ; the instruction size would at least double, which is not what we
19090 ; want even with ! optimize_size.
19091 (define_split
19092   [(set (match_operand 0 "flags_reg_operand" "")
19093         (match_operator 1 "compare_operator"
19094           [(and (match_operand:HI 2 "aligned_operand" "")
19095                 (match_operand:HI 3 "const_int_operand" ""))
19096            (const_int 0)]))]
19097   "! TARGET_PARTIAL_REG_STALL && reload_completed
19098    /* Ensure that the operand will remain sign-extended immediate.  */
19099    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19100    && ! TARGET_FAST_PREFIX
19101    && ! optimize_size"
19102   [(set (match_dup 0)
19103         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19104                          (const_int 0)]))]
19106   operands[3]
19107     = gen_int_mode (INTVAL (operands[3])
19108                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19109   operands[2] = gen_lowpart (SImode, operands[2]);
19112 (define_split
19113   [(set (match_operand 0 "register_operand" "")
19114         (neg (match_operand 1 "register_operand" "")))
19115    (clobber (reg:CC FLAGS_REG))]
19116   "! TARGET_PARTIAL_REG_STALL && reload_completed
19117    && (GET_MODE (operands[0]) == HImode
19118        || (GET_MODE (operands[0]) == QImode 
19119            && (TARGET_PROMOTE_QImode || optimize_size)))"
19120   [(parallel [(set (match_dup 0)
19121                    (neg:SI (match_dup 1)))
19122               (clobber (reg:CC FLAGS_REG))])]
19123   "operands[0] = gen_lowpart (SImode, operands[0]);
19124    operands[1] = gen_lowpart (SImode, operands[1]);")
19126 (define_split
19127   [(set (match_operand 0 "register_operand" "")
19128         (not (match_operand 1 "register_operand" "")))]
19129   "! TARGET_PARTIAL_REG_STALL && reload_completed
19130    && (GET_MODE (operands[0]) == HImode
19131        || (GET_MODE (operands[0]) == QImode 
19132            && (TARGET_PROMOTE_QImode || optimize_size)))"
19133   [(set (match_dup 0)
19134         (not:SI (match_dup 1)))]
19135   "operands[0] = gen_lowpart (SImode, operands[0]);
19136    operands[1] = gen_lowpart (SImode, operands[1]);")
19138 (define_split 
19139   [(set (match_operand 0 "register_operand" "")
19140         (if_then_else (match_operator 1 "comparison_operator" 
19141                                 [(reg FLAGS_REG) (const_int 0)])
19142                       (match_operand 2 "register_operand" "")
19143                       (match_operand 3 "register_operand" "")))]
19144   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19145    && (GET_MODE (operands[0]) == HImode
19146        || (GET_MODE (operands[0]) == QImode 
19147            && (TARGET_PROMOTE_QImode || optimize_size)))"
19148   [(set (match_dup 0)
19149         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19150   "operands[0] = gen_lowpart (SImode, operands[0]);
19151    operands[2] = gen_lowpart (SImode, operands[2]);
19152    operands[3] = gen_lowpart (SImode, operands[3]);")
19153                         
19155 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19156 ;; transform a complex memory operation into two memory to register operations.
19158 ;; Don't push memory operands
19159 (define_peephole2
19160   [(set (match_operand:SI 0 "push_operand" "")
19161         (match_operand:SI 1 "memory_operand" ""))
19162    (match_scratch:SI 2 "r")]
19163   "!optimize_size && !TARGET_PUSH_MEMORY
19164    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19165   [(set (match_dup 2) (match_dup 1))
19166    (set (match_dup 0) (match_dup 2))]
19167   "")
19169 (define_peephole2
19170   [(set (match_operand:DI 0 "push_operand" "")
19171         (match_operand:DI 1 "memory_operand" ""))
19172    (match_scratch:DI 2 "r")]
19173   "!optimize_size && !TARGET_PUSH_MEMORY
19174    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19175   [(set (match_dup 2) (match_dup 1))
19176    (set (match_dup 0) (match_dup 2))]
19177   "")
19179 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19180 ;; SImode pushes.
19181 (define_peephole2
19182   [(set (match_operand:SF 0 "push_operand" "")
19183         (match_operand:SF 1 "memory_operand" ""))
19184    (match_scratch:SF 2 "r")]
19185   "!optimize_size && !TARGET_PUSH_MEMORY
19186    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19187   [(set (match_dup 2) (match_dup 1))
19188    (set (match_dup 0) (match_dup 2))]
19189   "")
19191 (define_peephole2
19192   [(set (match_operand:HI 0 "push_operand" "")
19193         (match_operand:HI 1 "memory_operand" ""))
19194    (match_scratch:HI 2 "r")]
19195   "!optimize_size && !TARGET_PUSH_MEMORY
19196    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19197   [(set (match_dup 2) (match_dup 1))
19198    (set (match_dup 0) (match_dup 2))]
19199   "")
19201 (define_peephole2
19202   [(set (match_operand:QI 0 "push_operand" "")
19203         (match_operand:QI 1 "memory_operand" ""))
19204    (match_scratch:QI 2 "q")]
19205   "!optimize_size && !TARGET_PUSH_MEMORY
19206    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19207   [(set (match_dup 2) (match_dup 1))
19208    (set (match_dup 0) (match_dup 2))]
19209   "")
19211 ;; Don't move an immediate directly to memory when the instruction
19212 ;; gets too big.
19213 (define_peephole2
19214   [(match_scratch:SI 1 "r")
19215    (set (match_operand:SI 0 "memory_operand" "")
19216         (const_int 0))]
19217   "! optimize_size
19218    && ! TARGET_USE_MOV0
19219    && TARGET_SPLIT_LONG_MOVES
19220    && get_attr_length (insn) >= ix86_cost->large_insn
19221    && peep2_regno_dead_p (0, FLAGS_REG)"
19222   [(parallel [(set (match_dup 1) (const_int 0))
19223               (clobber (reg:CC FLAGS_REG))])
19224    (set (match_dup 0) (match_dup 1))]
19225   "")
19227 (define_peephole2
19228   [(match_scratch:HI 1 "r")
19229    (set (match_operand:HI 0 "memory_operand" "")
19230         (const_int 0))]
19231   "! optimize_size
19232    && ! TARGET_USE_MOV0
19233    && TARGET_SPLIT_LONG_MOVES
19234    && get_attr_length (insn) >= ix86_cost->large_insn
19235    && peep2_regno_dead_p (0, FLAGS_REG)"
19236   [(parallel [(set (match_dup 2) (const_int 0))
19237               (clobber (reg:CC FLAGS_REG))])
19238    (set (match_dup 0) (match_dup 1))]
19239   "operands[2] = gen_lowpart (SImode, operands[1]);")
19241 (define_peephole2
19242   [(match_scratch:QI 1 "q")
19243    (set (match_operand:QI 0 "memory_operand" "")
19244         (const_int 0))]
19245   "! optimize_size
19246    && ! TARGET_USE_MOV0
19247    && TARGET_SPLIT_LONG_MOVES
19248    && get_attr_length (insn) >= ix86_cost->large_insn
19249    && peep2_regno_dead_p (0, FLAGS_REG)"
19250   [(parallel [(set (match_dup 2) (const_int 0))
19251               (clobber (reg:CC FLAGS_REG))])
19252    (set (match_dup 0) (match_dup 1))]
19253   "operands[2] = gen_lowpart (SImode, operands[1]);")
19255 (define_peephole2
19256   [(match_scratch:SI 2 "r")
19257    (set (match_operand:SI 0 "memory_operand" "")
19258         (match_operand:SI 1 "immediate_operand" ""))]
19259   "! optimize_size
19260    && get_attr_length (insn) >= ix86_cost->large_insn
19261    && TARGET_SPLIT_LONG_MOVES"
19262   [(set (match_dup 2) (match_dup 1))
19263    (set (match_dup 0) (match_dup 2))]
19264   "")
19266 (define_peephole2
19267   [(match_scratch:HI 2 "r")
19268    (set (match_operand:HI 0 "memory_operand" "")
19269         (match_operand:HI 1 "immediate_operand" ""))]
19270   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19271   && TARGET_SPLIT_LONG_MOVES"
19272   [(set (match_dup 2) (match_dup 1))
19273    (set (match_dup 0) (match_dup 2))]
19274   "")
19276 (define_peephole2
19277   [(match_scratch:QI 2 "q")
19278    (set (match_operand:QI 0 "memory_operand" "")
19279         (match_operand:QI 1 "immediate_operand" ""))]
19280   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19281   && TARGET_SPLIT_LONG_MOVES"
19282   [(set (match_dup 2) (match_dup 1))
19283    (set (match_dup 0) (match_dup 2))]
19284   "")
19286 ;; Don't compare memory with zero, load and use a test instead.
19287 (define_peephole2
19288   [(set (match_operand 0 "flags_reg_operand" "")
19289         (match_operator 1 "compare_operator"
19290           [(match_operand:SI 2 "memory_operand" "")
19291            (const_int 0)]))
19292    (match_scratch:SI 3 "r")]
19293   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19294   [(set (match_dup 3) (match_dup 2))
19295    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19296   "")
19298 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19299 ;; Don't split NOTs with a displacement operand, because resulting XOR
19300 ;; will not be pairable anyway.
19302 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19303 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19304 ;; so this split helps here as well.
19306 ;; Note: Can't do this as a regular split because we can't get proper
19307 ;; lifetime information then.
19309 (define_peephole2
19310   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19311         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19312   "!optimize_size
19313    && peep2_regno_dead_p (0, FLAGS_REG)
19314    && ((TARGET_PENTIUM 
19315         && (GET_CODE (operands[0]) != MEM
19316             || !memory_displacement_operand (operands[0], SImode)))
19317        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19318   [(parallel [(set (match_dup 0)
19319                    (xor:SI (match_dup 1) (const_int -1)))
19320               (clobber (reg:CC FLAGS_REG))])]
19321   "")
19323 (define_peephole2
19324   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19325         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19326   "!optimize_size
19327    && peep2_regno_dead_p (0, FLAGS_REG)
19328    && ((TARGET_PENTIUM 
19329         && (GET_CODE (operands[0]) != MEM
19330             || !memory_displacement_operand (operands[0], HImode)))
19331        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19332   [(parallel [(set (match_dup 0)
19333                    (xor:HI (match_dup 1) (const_int -1)))
19334               (clobber (reg:CC FLAGS_REG))])]
19335   "")
19337 (define_peephole2
19338   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19339         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19340   "!optimize_size
19341    && peep2_regno_dead_p (0, FLAGS_REG)
19342    && ((TARGET_PENTIUM 
19343         && (GET_CODE (operands[0]) != MEM
19344             || !memory_displacement_operand (operands[0], QImode)))
19345        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19346   [(parallel [(set (match_dup 0)
19347                    (xor:QI (match_dup 1) (const_int -1)))
19348               (clobber (reg:CC FLAGS_REG))])]
19349   "")
19351 ;; Non pairable "test imm, reg" instructions can be translated to
19352 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19353 ;; byte opcode instead of two, have a short form for byte operands),
19354 ;; so do it for other CPUs as well.  Given that the value was dead,
19355 ;; this should not create any new dependencies.  Pass on the sub-word
19356 ;; versions if we're concerned about partial register stalls.
19358 (define_peephole2
19359   [(set (match_operand 0 "flags_reg_operand" "")
19360         (match_operator 1 "compare_operator"
19361           [(and:SI (match_operand:SI 2 "register_operand" "")
19362                    (match_operand:SI 3 "immediate_operand" ""))
19363            (const_int 0)]))]
19364   "ix86_match_ccmode (insn, CCNOmode)
19365    && (true_regnum (operands[2]) != 0
19366        || satisfies_constraint_K (operands[3]))
19367    && peep2_reg_dead_p (1, operands[2])"
19368   [(parallel
19369      [(set (match_dup 0)
19370            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19371                             (const_int 0)]))
19372       (set (match_dup 2)
19373            (and:SI (match_dup 2) (match_dup 3)))])]
19374   "")
19376 ;; We don't need to handle HImode case, because it will be promoted to SImode
19377 ;; on ! TARGET_PARTIAL_REG_STALL
19379 (define_peephole2
19380   [(set (match_operand 0 "flags_reg_operand" "")
19381         (match_operator 1 "compare_operator"
19382           [(and:QI (match_operand:QI 2 "register_operand" "")
19383                    (match_operand:QI 3 "immediate_operand" ""))
19384            (const_int 0)]))]
19385   "! TARGET_PARTIAL_REG_STALL
19386    && ix86_match_ccmode (insn, CCNOmode)
19387    && true_regnum (operands[2]) != 0
19388    && peep2_reg_dead_p (1, operands[2])"
19389   [(parallel
19390      [(set (match_dup 0)
19391            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19392                             (const_int 0)]))
19393       (set (match_dup 2)
19394            (and:QI (match_dup 2) (match_dup 3)))])]
19395   "")
19397 (define_peephole2
19398   [(set (match_operand 0 "flags_reg_operand" "")
19399         (match_operator 1 "compare_operator"
19400           [(and:SI
19401              (zero_extract:SI
19402                (match_operand 2 "ext_register_operand" "")
19403                (const_int 8)
19404                (const_int 8))
19405              (match_operand 3 "const_int_operand" ""))
19406            (const_int 0)]))]
19407   "! TARGET_PARTIAL_REG_STALL
19408    && ix86_match_ccmode (insn, CCNOmode)
19409    && true_regnum (operands[2]) != 0
19410    && peep2_reg_dead_p (1, operands[2])"
19411   [(parallel [(set (match_dup 0)
19412                    (match_op_dup 1
19413                      [(and:SI
19414                         (zero_extract:SI
19415                           (match_dup 2)
19416                           (const_int 8)
19417                           (const_int 8))
19418                         (match_dup 3))
19419                       (const_int 0)]))
19420               (set (zero_extract:SI (match_dup 2)
19421                                     (const_int 8)
19422                                     (const_int 8))
19423                    (and:SI 
19424                      (zero_extract:SI
19425                        (match_dup 2)
19426                        (const_int 8)
19427                        (const_int 8))
19428                      (match_dup 3)))])]
19429   "")
19431 ;; Don't do logical operations with memory inputs.
19432 (define_peephole2
19433   [(match_scratch:SI 2 "r")
19434    (parallel [(set (match_operand:SI 0 "register_operand" "")
19435                    (match_operator:SI 3 "arith_or_logical_operator"
19436                      [(match_dup 0)
19437                       (match_operand:SI 1 "memory_operand" "")]))
19438               (clobber (reg:CC FLAGS_REG))])]
19439   "! optimize_size && ! TARGET_READ_MODIFY"
19440   [(set (match_dup 2) (match_dup 1))
19441    (parallel [(set (match_dup 0)
19442                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19443               (clobber (reg:CC FLAGS_REG))])]
19444   "")
19446 (define_peephole2
19447   [(match_scratch:SI 2 "r")
19448    (parallel [(set (match_operand:SI 0 "register_operand" "")
19449                    (match_operator:SI 3 "arith_or_logical_operator"
19450                      [(match_operand:SI 1 "memory_operand" "")
19451                       (match_dup 0)]))
19452               (clobber (reg:CC FLAGS_REG))])]
19453   "! optimize_size && ! TARGET_READ_MODIFY"
19454   [(set (match_dup 2) (match_dup 1))
19455    (parallel [(set (match_dup 0)
19456                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19457               (clobber (reg:CC FLAGS_REG))])]
19458   "")
19460 ; Don't do logical operations with memory outputs
19462 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19463 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19464 ; the same decoder scheduling characteristics as the original.
19466 (define_peephole2
19467   [(match_scratch:SI 2 "r")
19468    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19469                    (match_operator:SI 3 "arith_or_logical_operator"
19470                      [(match_dup 0)
19471                       (match_operand:SI 1 "nonmemory_operand" "")]))
19472               (clobber (reg:CC FLAGS_REG))])]
19473   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19474   [(set (match_dup 2) (match_dup 0))
19475    (parallel [(set (match_dup 2)
19476                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19477               (clobber (reg:CC FLAGS_REG))])
19478    (set (match_dup 0) (match_dup 2))]
19479   "")
19481 (define_peephole2
19482   [(match_scratch:SI 2 "r")
19483    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19484                    (match_operator:SI 3 "arith_or_logical_operator"
19485                      [(match_operand:SI 1 "nonmemory_operand" "")
19486                       (match_dup 0)]))
19487               (clobber (reg:CC FLAGS_REG))])]
19488   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19489   [(set (match_dup 2) (match_dup 0))
19490    (parallel [(set (match_dup 2)
19491                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19492               (clobber (reg:CC FLAGS_REG))])
19493    (set (match_dup 0) (match_dup 2))]
19494   "")
19496 ;; Attempt to always use XOR for zeroing registers.
19497 (define_peephole2
19498   [(set (match_operand 0 "register_operand" "")
19499         (match_operand 1 "const0_operand" ""))]
19500   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19501    && (! TARGET_USE_MOV0 || optimize_size)
19502    && GENERAL_REG_P (operands[0])
19503    && peep2_regno_dead_p (0, FLAGS_REG)"
19504   [(parallel [(set (match_dup 0) (const_int 0))
19505               (clobber (reg:CC FLAGS_REG))])]
19507   operands[0] = gen_lowpart (word_mode, operands[0]);
19510 (define_peephole2
19511   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19512         (const_int 0))]
19513   "(GET_MODE (operands[0]) == QImode
19514     || GET_MODE (operands[0]) == HImode)
19515    && (! TARGET_USE_MOV0 || optimize_size)
19516    && peep2_regno_dead_p (0, FLAGS_REG)"
19517   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19518               (clobber (reg:CC FLAGS_REG))])])
19520 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19521 (define_peephole2
19522   [(set (match_operand 0 "register_operand" "")
19523         (const_int -1))]
19524   "(GET_MODE (operands[0]) == HImode
19525     || GET_MODE (operands[0]) == SImode 
19526     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19527    && (optimize_size || TARGET_PENTIUM)
19528    && peep2_regno_dead_p (0, FLAGS_REG)"
19529   [(parallel [(set (match_dup 0) (const_int -1))
19530               (clobber (reg:CC FLAGS_REG))])]
19531   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19532                               operands[0]);")
19534 ;; Attempt to convert simple leas to adds. These can be created by
19535 ;; move expanders.
19536 (define_peephole2
19537   [(set (match_operand:SI 0 "register_operand" "")
19538         (plus:SI (match_dup 0)
19539                  (match_operand:SI 1 "nonmemory_operand" "")))]
19540   "peep2_regno_dead_p (0, FLAGS_REG)"
19541   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19542               (clobber (reg:CC FLAGS_REG))])]
19543   "")
19545 (define_peephole2
19546   [(set (match_operand:SI 0 "register_operand" "")
19547         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19548                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19549   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19550   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19551               (clobber (reg:CC FLAGS_REG))])]
19552   "operands[2] = gen_lowpart (SImode, operands[2]);")
19554 (define_peephole2
19555   [(set (match_operand:DI 0 "register_operand" "")
19556         (plus:DI (match_dup 0)
19557                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19558   "peep2_regno_dead_p (0, FLAGS_REG)"
19559   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19560               (clobber (reg:CC FLAGS_REG))])]
19561   "")
19563 (define_peephole2
19564   [(set (match_operand:SI 0 "register_operand" "")
19565         (mult:SI (match_dup 0)
19566                  (match_operand:SI 1 "const_int_operand" "")))]
19567   "exact_log2 (INTVAL (operands[1])) >= 0
19568    && peep2_regno_dead_p (0, FLAGS_REG)"
19569   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19570               (clobber (reg:CC FLAGS_REG))])]
19571   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19573 (define_peephole2
19574   [(set (match_operand:DI 0 "register_operand" "")
19575         (mult:DI (match_dup 0)
19576                  (match_operand:DI 1 "const_int_operand" "")))]
19577   "exact_log2 (INTVAL (operands[1])) >= 0
19578    && peep2_regno_dead_p (0, FLAGS_REG)"
19579   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19580               (clobber (reg:CC FLAGS_REG))])]
19581   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19583 (define_peephole2
19584   [(set (match_operand:SI 0 "register_operand" "")
19585         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19586                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19587   "exact_log2 (INTVAL (operands[2])) >= 0
19588    && REGNO (operands[0]) == REGNO (operands[1])
19589    && peep2_regno_dead_p (0, FLAGS_REG)"
19590   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19591               (clobber (reg:CC FLAGS_REG))])]
19592   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19594 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19595 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19596 ;; many CPUs it is also faster, since special hardware to avoid esp
19597 ;; dependencies is present.
19599 ;; While some of these conversions may be done using splitters, we use peepholes
19600 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19602 ;; Convert prologue esp subtractions to push.
19603 ;; We need register to push.  In order to keep verify_flow_info happy we have
19604 ;; two choices
19605 ;; - use scratch and clobber it in order to avoid dependencies
19606 ;; - use already live register
19607 ;; We can't use the second way right now, since there is no reliable way how to
19608 ;; verify that given register is live.  First choice will also most likely in
19609 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19610 ;; call clobbered registers are dead.  We may want to use base pointer as an
19611 ;; alternative when no register is available later.
19613 (define_peephole2
19614   [(match_scratch:SI 0 "r")
19615    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19616               (clobber (reg:CC FLAGS_REG))
19617               (clobber (mem:BLK (scratch)))])]
19618   "optimize_size || !TARGET_SUB_ESP_4"
19619   [(clobber (match_dup 0))
19620    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19621               (clobber (mem:BLK (scratch)))])])
19623 (define_peephole2
19624   [(match_scratch:SI 0 "r")
19625    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19626               (clobber (reg:CC FLAGS_REG))
19627               (clobber (mem:BLK (scratch)))])]
19628   "optimize_size || !TARGET_SUB_ESP_8"
19629   [(clobber (match_dup 0))
19630    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19631    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19632               (clobber (mem:BLK (scratch)))])])
19634 ;; Convert esp subtractions to push.
19635 (define_peephole2
19636   [(match_scratch:SI 0 "r")
19637    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19638               (clobber (reg:CC FLAGS_REG))])]
19639   "optimize_size || !TARGET_SUB_ESP_4"
19640   [(clobber (match_dup 0))
19641    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19643 (define_peephole2
19644   [(match_scratch:SI 0 "r")
19645    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19646               (clobber (reg:CC FLAGS_REG))])]
19647   "optimize_size || !TARGET_SUB_ESP_8"
19648   [(clobber (match_dup 0))
19649    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19650    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19652 ;; Convert epilogue deallocator to pop.
19653 (define_peephole2
19654   [(match_scratch:SI 0 "r")
19655    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19656               (clobber (reg:CC FLAGS_REG))
19657               (clobber (mem:BLK (scratch)))])]
19658   "optimize_size || !TARGET_ADD_ESP_4"
19659   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19660               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19661               (clobber (mem:BLK (scratch)))])]
19662   "")
19664 ;; Two pops case is tricky, since pop causes dependency on destination register.
19665 ;; We use two registers if available.
19666 (define_peephole2
19667   [(match_scratch:SI 0 "r")
19668    (match_scratch:SI 1 "r")
19669    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19670               (clobber (reg:CC FLAGS_REG))
19671               (clobber (mem:BLK (scratch)))])]
19672   "optimize_size || !TARGET_ADD_ESP_8"
19673   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19674               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19675               (clobber (mem:BLK (scratch)))])
19676    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19677               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19678   "")
19680 (define_peephole2
19681   [(match_scratch:SI 0 "r")
19682    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19683               (clobber (reg:CC FLAGS_REG))
19684               (clobber (mem:BLK (scratch)))])]
19685   "optimize_size"
19686   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19687               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19688               (clobber (mem:BLK (scratch)))])
19689    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19690               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19691   "")
19693 ;; Convert esp additions to pop.
19694 (define_peephole2
19695   [(match_scratch:SI 0 "r")
19696    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19697               (clobber (reg:CC FLAGS_REG))])]
19698   ""
19699   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19700               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19701   "")
19703 ;; Two pops case is tricky, since pop causes dependency on destination register.
19704 ;; We use two registers if available.
19705 (define_peephole2
19706   [(match_scratch:SI 0 "r")
19707    (match_scratch:SI 1 "r")
19708    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19709               (clobber (reg:CC FLAGS_REG))])]
19710   ""
19711   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19712               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19713    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19714               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19715   "")
19717 (define_peephole2
19718   [(match_scratch:SI 0 "r")
19719    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19720               (clobber (reg:CC FLAGS_REG))])]
19721   "optimize_size"
19722   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19723               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19724    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19725               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19726   "")
19728 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19729 ;; required and register dies.  Similarly for 128 to plus -128.
19730 (define_peephole2
19731   [(set (match_operand 0 "flags_reg_operand" "")
19732         (match_operator 1 "compare_operator"
19733           [(match_operand 2 "register_operand" "")
19734            (match_operand 3 "const_int_operand" "")]))]
19735   "(INTVAL (operands[3]) == -1
19736     || INTVAL (operands[3]) == 1
19737     || INTVAL (operands[3]) == 128)
19738    && ix86_match_ccmode (insn, CCGCmode)
19739    && peep2_reg_dead_p (1, operands[2])"
19740   [(parallel [(set (match_dup 0)
19741                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19742               (clobber (match_dup 2))])]
19743   "")
19745 (define_peephole2
19746   [(match_scratch:DI 0 "r")
19747    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19748               (clobber (reg:CC FLAGS_REG))
19749               (clobber (mem:BLK (scratch)))])]
19750   "optimize_size || !TARGET_SUB_ESP_4"
19751   [(clobber (match_dup 0))
19752    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19753               (clobber (mem:BLK (scratch)))])])
19755 (define_peephole2
19756   [(match_scratch:DI 0 "r")
19757    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19758               (clobber (reg:CC FLAGS_REG))
19759               (clobber (mem:BLK (scratch)))])]
19760   "optimize_size || !TARGET_SUB_ESP_8"
19761   [(clobber (match_dup 0))
19762    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19763    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19764               (clobber (mem:BLK (scratch)))])])
19766 ;; Convert esp subtractions to push.
19767 (define_peephole2
19768   [(match_scratch:DI 0 "r")
19769    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19770               (clobber (reg:CC FLAGS_REG))])]
19771   "optimize_size || !TARGET_SUB_ESP_4"
19772   [(clobber (match_dup 0))
19773    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19775 (define_peephole2
19776   [(match_scratch:DI 0 "r")
19777    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19778               (clobber (reg:CC FLAGS_REG))])]
19779   "optimize_size || !TARGET_SUB_ESP_8"
19780   [(clobber (match_dup 0))
19781    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19782    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19784 ;; Convert epilogue deallocator to pop.
19785 (define_peephole2
19786   [(match_scratch:DI 0 "r")
19787    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19788               (clobber (reg:CC FLAGS_REG))
19789               (clobber (mem:BLK (scratch)))])]
19790   "optimize_size || !TARGET_ADD_ESP_4"
19791   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19792               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19793               (clobber (mem:BLK (scratch)))])]
19794   "")
19796 ;; Two pops case is tricky, since pop causes dependency on destination register.
19797 ;; We use two registers if available.
19798 (define_peephole2
19799   [(match_scratch:DI 0 "r")
19800    (match_scratch:DI 1 "r")
19801    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19802               (clobber (reg:CC FLAGS_REG))
19803               (clobber (mem:BLK (scratch)))])]
19804   "optimize_size || !TARGET_ADD_ESP_8"
19805   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19806               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19807               (clobber (mem:BLK (scratch)))])
19808    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19809               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19810   "")
19812 (define_peephole2
19813   [(match_scratch:DI 0 "r")
19814    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19815               (clobber (reg:CC FLAGS_REG))
19816               (clobber (mem:BLK (scratch)))])]
19817   "optimize_size"
19818   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19819               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19820               (clobber (mem:BLK (scratch)))])
19821    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19822               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19823   "")
19825 ;; Convert esp additions to pop.
19826 (define_peephole2
19827   [(match_scratch:DI 0 "r")
19828    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19829               (clobber (reg:CC FLAGS_REG))])]
19830   ""
19831   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19832               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19833   "")
19835 ;; Two pops case is tricky, since pop causes dependency on destination register.
19836 ;; We use two registers if available.
19837 (define_peephole2
19838   [(match_scratch:DI 0 "r")
19839    (match_scratch:DI 1 "r")
19840    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19841               (clobber (reg:CC FLAGS_REG))])]
19842   ""
19843   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19844               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19845    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19846               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19847   "")
19849 (define_peephole2
19850   [(match_scratch:DI 0 "r")
19851    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19852               (clobber (reg:CC FLAGS_REG))])]
19853   "optimize_size"
19854   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19855               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19856    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19857               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19858   "")
19860 ;; Convert imul by three, five and nine into lea
19861 (define_peephole2
19862   [(parallel
19863     [(set (match_operand:SI 0 "register_operand" "")
19864           (mult:SI (match_operand:SI 1 "register_operand" "")
19865                    (match_operand:SI 2 "const_int_operand" "")))
19866      (clobber (reg:CC FLAGS_REG))])]
19867   "INTVAL (operands[2]) == 3
19868    || INTVAL (operands[2]) == 5
19869    || INTVAL (operands[2]) == 9"
19870   [(set (match_dup 0)
19871         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19872                  (match_dup 1)))]
19873   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19875 (define_peephole2
19876   [(parallel
19877     [(set (match_operand:SI 0 "register_operand" "")
19878           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19879                    (match_operand:SI 2 "const_int_operand" "")))
19880      (clobber (reg:CC FLAGS_REG))])]
19881   "!optimize_size 
19882    && (INTVAL (operands[2]) == 3
19883        || INTVAL (operands[2]) == 5
19884        || INTVAL (operands[2]) == 9)"
19885   [(set (match_dup 0) (match_dup 1))
19886    (set (match_dup 0)
19887         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19888                  (match_dup 0)))]
19889   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19891 (define_peephole2
19892   [(parallel
19893     [(set (match_operand:DI 0 "register_operand" "")
19894           (mult:DI (match_operand:DI 1 "register_operand" "")
19895                    (match_operand:DI 2 "const_int_operand" "")))
19896      (clobber (reg:CC FLAGS_REG))])]
19897   "TARGET_64BIT
19898    && (INTVAL (operands[2]) == 3
19899        || INTVAL (operands[2]) == 5
19900        || INTVAL (operands[2]) == 9)"
19901   [(set (match_dup 0)
19902         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19903                  (match_dup 1)))]
19904   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19906 (define_peephole2
19907   [(parallel
19908     [(set (match_operand:DI 0 "register_operand" "")
19909           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19910                    (match_operand:DI 2 "const_int_operand" "")))
19911      (clobber (reg:CC FLAGS_REG))])]
19912   "TARGET_64BIT
19913    && !optimize_size 
19914    && (INTVAL (operands[2]) == 3
19915        || INTVAL (operands[2]) == 5
19916        || INTVAL (operands[2]) == 9)"
19917   [(set (match_dup 0) (match_dup 1))
19918    (set (match_dup 0)
19919         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19920                  (match_dup 0)))]
19921   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19923 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19924 ;; imul $32bit_imm, reg, reg is direct decoded.
19925 (define_peephole2
19926   [(match_scratch:DI 3 "r")
19927    (parallel [(set (match_operand:DI 0 "register_operand" "")
19928                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19929                             (match_operand:DI 2 "immediate_operand" "")))
19930               (clobber (reg:CC FLAGS_REG))])]
19931   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19932    && !satisfies_constraint_K (operands[2])"
19933   [(set (match_dup 3) (match_dup 1))
19934    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19935               (clobber (reg:CC FLAGS_REG))])]
19938 (define_peephole2
19939   [(match_scratch:SI 3 "r")
19940    (parallel [(set (match_operand:SI 0 "register_operand" "")
19941                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19942                             (match_operand:SI 2 "immediate_operand" "")))
19943               (clobber (reg:CC FLAGS_REG))])]
19944   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19945    && !satisfies_constraint_K (operands[2])"
19946   [(set (match_dup 3) (match_dup 1))
19947    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19948               (clobber (reg:CC FLAGS_REG))])]
19951 (define_peephole2
19952   [(match_scratch:SI 3 "r")
19953    (parallel [(set (match_operand:DI 0 "register_operand" "")
19954                    (zero_extend:DI
19955                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19956                               (match_operand:SI 2 "immediate_operand" ""))))
19957               (clobber (reg:CC FLAGS_REG))])]
19958   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19959    && !satisfies_constraint_K (operands[2])"
19960   [(set (match_dup 3) (match_dup 1))
19961    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19962               (clobber (reg:CC FLAGS_REG))])]
19965 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19966 ;; Convert it into imul reg, reg
19967 ;; It would be better to force assembler to encode instruction using long
19968 ;; immediate, but there is apparently no way to do so.
19969 (define_peephole2
19970   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19971                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19972                             (match_operand:DI 2 "const_int_operand" "")))
19973               (clobber (reg:CC FLAGS_REG))])
19974    (match_scratch:DI 3 "r")]
19975   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19976    && satisfies_constraint_K (operands[2])"
19977   [(set (match_dup 3) (match_dup 2))
19978    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19979               (clobber (reg:CC FLAGS_REG))])]
19981   if (!rtx_equal_p (operands[0], operands[1]))
19982     emit_move_insn (operands[0], operands[1]);
19985 (define_peephole2
19986   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19987                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19988                             (match_operand:SI 2 "const_int_operand" "")))
19989               (clobber (reg:CC FLAGS_REG))])
19990    (match_scratch:SI 3 "r")]
19991   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19992    && satisfies_constraint_K (operands[2])"
19993   [(set (match_dup 3) (match_dup 2))
19994    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19995               (clobber (reg:CC FLAGS_REG))])]
19997   if (!rtx_equal_p (operands[0], operands[1]))
19998     emit_move_insn (operands[0], operands[1]);
20001 (define_peephole2
20002   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20003                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20004                             (match_operand:HI 2 "immediate_operand" "")))
20005               (clobber (reg:CC FLAGS_REG))])
20006    (match_scratch:HI 3 "r")]
20007   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20008   [(set (match_dup 3) (match_dup 2))
20009    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20010               (clobber (reg:CC FLAGS_REG))])]
20012   if (!rtx_equal_p (operands[0], operands[1]))
20013     emit_move_insn (operands[0], operands[1]);
20016 ;; After splitting up read-modify operations, array accesses with memory
20017 ;; operands might end up in form:
20018 ;;  sall    $2, %eax
20019 ;;  movl    4(%esp), %edx
20020 ;;  addl    %edx, %eax
20021 ;; instead of pre-splitting:
20022 ;;  sall    $2, %eax
20023 ;;  addl    4(%esp), %eax
20024 ;; Turn it into:
20025 ;;  movl    4(%esp), %edx
20026 ;;  leal    (%edx,%eax,4), %eax
20028 (define_peephole2
20029   [(parallel [(set (match_operand 0 "register_operand" "")
20030                    (ashift (match_operand 1 "register_operand" "")
20031                            (match_operand 2 "const_int_operand" "")))
20032                (clobber (reg:CC FLAGS_REG))])
20033    (set (match_operand 3 "register_operand")
20034         (match_operand 4 "x86_64_general_operand" ""))
20035    (parallel [(set (match_operand 5 "register_operand" "")
20036                    (plus (match_operand 6 "register_operand" "")
20037                          (match_operand 7 "register_operand" "")))
20038                    (clobber (reg:CC FLAGS_REG))])]
20039   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20040    /* Validate MODE for lea.  */
20041    && ((!TARGET_PARTIAL_REG_STALL
20042         && (GET_MODE (operands[0]) == QImode
20043             || GET_MODE (operands[0]) == HImode))
20044        || GET_MODE (operands[0]) == SImode 
20045        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20046    /* We reorder load and the shift.  */
20047    && !rtx_equal_p (operands[1], operands[3])
20048    && !reg_overlap_mentioned_p (operands[0], operands[4])
20049    /* Last PLUS must consist of operand 0 and 3.  */
20050    && !rtx_equal_p (operands[0], operands[3])
20051    && (rtx_equal_p (operands[3], operands[6])
20052        || rtx_equal_p (operands[3], operands[7]))
20053    && (rtx_equal_p (operands[0], operands[6])
20054        || rtx_equal_p (operands[0], operands[7]))
20055    /* The intermediate operand 0 must die or be same as output.  */
20056    && (rtx_equal_p (operands[0], operands[5])
20057        || peep2_reg_dead_p (3, operands[0]))"
20058   [(set (match_dup 3) (match_dup 4))
20059    (set (match_dup 0) (match_dup 1))]
20061   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20062   int scale = 1 << INTVAL (operands[2]);
20063   rtx index = gen_lowpart (Pmode, operands[1]);
20064   rtx base = gen_lowpart (Pmode, operands[3]);
20065   rtx dest = gen_lowpart (mode, operands[5]);
20067   operands[1] = gen_rtx_PLUS (Pmode, base,
20068                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20069   if (mode != Pmode)
20070     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20071   operands[0] = dest;
20074 ;; Call-value patterns last so that the wildcard operand does not
20075 ;; disrupt insn-recog's switch tables.
20077 (define_insn "*call_value_pop_0"
20078   [(set (match_operand 0 "" "")
20079         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20080               (match_operand:SI 2 "" "")))
20081    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20082                             (match_operand:SI 3 "immediate_operand" "")))]
20083   "!TARGET_64BIT"
20085   if (SIBLING_CALL_P (insn))
20086     return "jmp\t%P1";
20087   else
20088     return "call\t%P1";
20090   [(set_attr "type" "callv")])
20092 (define_insn "*call_value_pop_1"
20093   [(set (match_operand 0 "" "")
20094         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20095               (match_operand:SI 2 "" "")))
20096    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20097                             (match_operand:SI 3 "immediate_operand" "i")))]
20098   "!TARGET_64BIT"
20100   if (constant_call_address_operand (operands[1], Pmode))
20101     {
20102       if (SIBLING_CALL_P (insn))
20103         return "jmp\t%P1";
20104       else
20105         return "call\t%P1";
20106     }
20107   if (SIBLING_CALL_P (insn))
20108     return "jmp\t%A1";
20109   else
20110     return "call\t%A1";
20112   [(set_attr "type" "callv")])
20114 (define_insn "*call_value_0"
20115   [(set (match_operand 0 "" "")
20116         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20117               (match_operand:SI 2 "" "")))]
20118   "!TARGET_64BIT"
20120   if (SIBLING_CALL_P (insn))
20121     return "jmp\t%P1";
20122   else
20123     return "call\t%P1";
20125   [(set_attr "type" "callv")])
20127 (define_insn "*call_value_0_rex64"
20128   [(set (match_operand 0 "" "")
20129         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20130               (match_operand:DI 2 "const_int_operand" "")))]
20131   "TARGET_64BIT"
20133   if (SIBLING_CALL_P (insn))
20134     return "jmp\t%P1";
20135   else
20136     return "call\t%P1";
20138   [(set_attr "type" "callv")])
20140 (define_insn "*call_value_1"
20141   [(set (match_operand 0 "" "")
20142         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20143               (match_operand:SI 2 "" "")))]
20144   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20146   if (constant_call_address_operand (operands[1], Pmode))
20147     return "call\t%P1";
20148   return "call\t%A1";
20150   [(set_attr "type" "callv")])
20152 (define_insn "*sibcall_value_1"
20153   [(set (match_operand 0 "" "")
20154         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20155               (match_operand:SI 2 "" "")))]
20156   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20158   if (constant_call_address_operand (operands[1], Pmode))
20159     return "jmp\t%P1";
20160   return "jmp\t%A1";
20162   [(set_attr "type" "callv")])
20164 (define_insn "*call_value_1_rex64"
20165   [(set (match_operand 0 "" "")
20166         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20167               (match_operand:DI 2 "" "")))]
20168   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20170   if (constant_call_address_operand (operands[1], Pmode))
20171     return "call\t%P1";
20172   return "call\t%A1";
20174   [(set_attr "type" "callv")])
20176 (define_insn "*sibcall_value_1_rex64"
20177   [(set (match_operand 0 "" "")
20178         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20179               (match_operand:DI 2 "" "")))]
20180   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20181   "jmp\t%P1"
20182   [(set_attr "type" "callv")])
20184 (define_insn "*sibcall_value_1_rex64_v"
20185   [(set (match_operand 0 "" "")
20186         (call (mem:QI (reg:DI 40))
20187               (match_operand:DI 1 "" "")))]
20188   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20189   "jmp\t*%%r11"
20190   [(set_attr "type" "callv")])
20192 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20193 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20194 ;; caught for use by garbage collectors and the like.  Using an insn that
20195 ;; maps to SIGILL makes it more likely the program will rightfully die.
20196 ;; Keeping with tradition, "6" is in honor of #UD.
20197 (define_insn "trap"
20198   [(trap_if (const_int 1) (const_int 6))]
20199   ""
20200   { return ASM_SHORT "0x0b0f"; }
20201   [(set_attr "length" "2")])
20203 (define_expand "sse_prologue_save"
20204   [(parallel [(set (match_operand:BLK 0 "" "")
20205                    (unspec:BLK [(reg:DI 21)
20206                                 (reg:DI 22)
20207                                 (reg:DI 23)
20208                                 (reg:DI 24)
20209                                 (reg:DI 25)
20210                                 (reg:DI 26)
20211                                 (reg:DI 27)
20212                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20213               (use (match_operand:DI 1 "register_operand" ""))
20214               (use (match_operand:DI 2 "immediate_operand" ""))
20215               (use (label_ref:DI (match_operand 3 "" "")))])]
20216   "TARGET_64BIT"
20217   "")
20219 (define_insn "*sse_prologue_save_insn"
20220   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20221                           (match_operand:DI 4 "const_int_operand" "n")))
20222         (unspec:BLK [(reg:DI 21)
20223                      (reg:DI 22)
20224                      (reg:DI 23)
20225                      (reg:DI 24)
20226                      (reg:DI 25)
20227                      (reg:DI 26)
20228                      (reg:DI 27)
20229                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20230    (use (match_operand:DI 1 "register_operand" "r"))
20231    (use (match_operand:DI 2 "const_int_operand" "i"))
20232    (use (label_ref:DI (match_operand 3 "" "X")))]
20233   "TARGET_64BIT
20234    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20235    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20236   "*
20238   int i;
20239   operands[0] = gen_rtx_MEM (Pmode,
20240                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20241   output_asm_insn (\"jmp\\t%A1\", operands);
20242   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20243     {
20244       operands[4] = adjust_address (operands[0], DImode, i*16);
20245       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20246       PUT_MODE (operands[4], TImode);
20247       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20248         output_asm_insn (\"rex\", operands);
20249       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20250     }
20251   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20252                              CODE_LABEL_NUMBER (operands[3]));
20253   RET;
20255   "
20256   [(set_attr "type" "other")
20257    (set_attr "length_immediate" "0")
20258    (set_attr "length_address" "0")
20259    (set_attr "length" "135")
20260    (set_attr "memory" "store")
20261    (set_attr "modrm" "0")
20262    (set_attr "mode" "DI")])
20264 (define_expand "prefetch"
20265   [(prefetch (match_operand 0 "address_operand" "")
20266              (match_operand:SI 1 "const_int_operand" "")
20267              (match_operand:SI 2 "const_int_operand" ""))]
20268   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20270   int rw = INTVAL (operands[1]);
20271   int locality = INTVAL (operands[2]);
20273   gcc_assert (rw == 0 || rw == 1);
20274   gcc_assert (locality >= 0 && locality <= 3);
20275   gcc_assert (GET_MODE (operands[0]) == Pmode
20276               || GET_MODE (operands[0]) == VOIDmode);
20278   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20279      supported by SSE counterpart or the SSE prefetch is not available
20280      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20281      of locality.  */
20282   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20283     operands[2] = GEN_INT (3);
20284   else
20285     operands[1] = const0_rtx;
20288 (define_insn "*prefetch_sse"
20289   [(prefetch (match_operand:SI 0 "address_operand" "p")
20290              (const_int 0)
20291              (match_operand:SI 1 "const_int_operand" ""))]
20292   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20294   static const char * const patterns[4] = {
20295    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20296   };
20298   int locality = INTVAL (operands[1]);
20299   gcc_assert (locality >= 0 && locality <= 3);
20301   return patterns[locality];  
20303   [(set_attr "type" "sse")
20304    (set_attr "memory" "none")])
20306 (define_insn "*prefetch_sse_rex"
20307   [(prefetch (match_operand:DI 0 "address_operand" "p")
20308              (const_int 0)
20309              (match_operand:SI 1 "const_int_operand" ""))]
20310   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20312   static const char * const patterns[4] = {
20313    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20314   };
20316   int locality = INTVAL (operands[1]);
20317   gcc_assert (locality >= 0 && locality <= 3);
20319   return patterns[locality];  
20321   [(set_attr "type" "sse")
20322    (set_attr "memory" "none")])
20324 (define_insn "*prefetch_3dnow"
20325   [(prefetch (match_operand:SI 0 "address_operand" "p")
20326              (match_operand:SI 1 "const_int_operand" "n")
20327              (const_int 3))]
20328   "TARGET_3DNOW && !TARGET_64BIT"
20330   if (INTVAL (operands[1]) == 0)
20331     return "prefetch\t%a0";
20332   else
20333     return "prefetchw\t%a0";
20335   [(set_attr "type" "mmx")
20336    (set_attr "memory" "none")])
20338 (define_insn "*prefetch_3dnow_rex"
20339   [(prefetch (match_operand:DI 0 "address_operand" "p")
20340              (match_operand:SI 1 "const_int_operand" "n")
20341              (const_int 3))]
20342   "TARGET_3DNOW && TARGET_64BIT"
20344   if (INTVAL (operands[1]) == 0)
20345     return "prefetch\t%a0";
20346   else
20347     return "prefetchw\t%a0";
20349   [(set_attr "type" "mmx")
20350    (set_attr "memory" "none")])
20352 (define_expand "stack_protect_set"
20353   [(match_operand 0 "memory_operand" "")
20354    (match_operand 1 "memory_operand" "")]
20355   ""
20357 #ifdef TARGET_THREAD_SSP_OFFSET
20358   if (TARGET_64BIT)
20359     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20360                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20361   else
20362     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20363                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20364 #else
20365   if (TARGET_64BIT)
20366     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20367   else
20368     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20369 #endif
20370   DONE;
20373 (define_insn "stack_protect_set_si"
20374   [(set (match_operand:SI 0 "memory_operand" "=m")
20375         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20376    (set (match_scratch:SI 2 "=&r") (const_int 0))
20377    (clobber (reg:CC FLAGS_REG))]
20378   ""
20379   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20380   [(set_attr "type" "multi")])
20382 (define_insn "stack_protect_set_di"
20383   [(set (match_operand:DI 0 "memory_operand" "=m")
20384         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20385    (set (match_scratch:DI 2 "=&r") (const_int 0))
20386    (clobber (reg:CC FLAGS_REG))]
20387   "TARGET_64BIT"
20388   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20389   [(set_attr "type" "multi")])
20391 (define_insn "stack_tls_protect_set_si"
20392   [(set (match_operand:SI 0 "memory_operand" "=m")
20393         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20394    (set (match_scratch:SI 2 "=&r") (const_int 0))
20395    (clobber (reg:CC FLAGS_REG))]
20396   ""
20397   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20398   [(set_attr "type" "multi")])
20400 (define_insn "stack_tls_protect_set_di"
20401   [(set (match_operand:DI 0 "memory_operand" "=m")
20402         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20403    (set (match_scratch:DI 2 "=&r") (const_int 0))
20404    (clobber (reg:CC FLAGS_REG))]
20405   "TARGET_64BIT"
20406   "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20407   [(set_attr "type" "multi")])
20409 (define_expand "stack_protect_test"
20410   [(match_operand 0 "memory_operand" "")
20411    (match_operand 1 "memory_operand" "")
20412    (match_operand 2 "" "")]
20413   ""
20415   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20416   ix86_compare_op0 = operands[0];
20417   ix86_compare_op1 = operands[1];
20418   ix86_compare_emitted = flags;
20420 #ifdef TARGET_THREAD_SSP_OFFSET
20421   if (TARGET_64BIT)
20422     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20423                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20424   else
20425     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20426                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20427 #else
20428   if (TARGET_64BIT)
20429     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20430   else
20431     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20432 #endif
20433   emit_jump_insn (gen_beq (operands[2]));
20434   DONE;
20437 (define_insn "stack_protect_test_si"
20438   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20439         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20440                      (match_operand:SI 2 "memory_operand" "m")]
20441                     UNSPEC_SP_TEST))
20442    (clobber (match_scratch:SI 3 "=&r"))]
20443   ""
20444   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20445   [(set_attr "type" "multi")])
20447 (define_insn "stack_protect_test_di"
20448   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20449         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20450                      (match_operand:DI 2 "memory_operand" "m")]
20451                     UNSPEC_SP_TEST))
20452    (clobber (match_scratch:DI 3 "=&r"))]
20453   "TARGET_64BIT"
20454   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20455   [(set_attr "type" "multi")])
20457 (define_insn "stack_tls_protect_test_si"
20458   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20459         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20460                      (match_operand:SI 2 "const_int_operand" "i")]
20461                     UNSPEC_SP_TLS_TEST))
20462    (clobber (match_scratch:SI 3 "=r"))]
20463   ""
20464   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20465   [(set_attr "type" "multi")])
20467 (define_insn "stack_tls_protect_test_di"
20468   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20469         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20470                      (match_operand:DI 2 "const_int_operand" "i")]
20471                     UNSPEC_SP_TLS_TEST))
20472    (clobber (match_scratch:DI 3 "=r"))]
20473   "TARGET_64BIT"
20474   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20475   [(set_attr "type" "multi")])
20477 (include "sse.md")
20478 (include "mmx.md")
20479 (include "sync.md")